- Home /
 
Any way around WWW timeout on Android?
I'm working on a project that requires scene changes to be remote-controlled. My thought was to have the app call a WWW every few seconds, and change the scene based on the response. I'm running into issues, though: WWW tends to run into errors on a regular basis on android, and then it spends 60 seconds waiting to time-out before it will start another WWW and be able to get the scene change command. I've tried stopping the coroutine, disposing of the WWW, and starting a second coroutine, but nothing works on Android. Can anyone suggest a better way of going about this?
My code thus far:
     void Update(){
         if(Time.time - lastCheck > 2F && runRupdater == true){
             StartCoroutine(getCurrentScene ());
         }
     }
 
     //Get the current scene, then continue to check every two seconds. 
     IEnumerator getCurrentScene (){
         float thisCheck = Time.time;
         lastCheck = Time.time;
         
         string urlToCheck = "http://myurl/where.php?pi="+whichPresentation;
         
         WWW getScene = new WWW(urlToCheck);
         yield return getScene;
         
         if(Time.time - thisCheck > 3F){
             getScene.Dispose();
             yield break;
         }
         
         if(getScene.text != "null"){
             if(currentScene != int.Parse(getScene.text)){
                 int.TryParse(getScene.text, out currentScene);
                 StartCoroutine(ActOnScene ());
             }
         }
     }
 
              Answer by peacefulshade · Jun 26, 2014 at 12:24 PM
If anyone stumbles on this, on android devices the WWW.Dispose method won't return immediately after called but will hang until the timeout is done or an error occurs; if the connection is slow (on the subway 4 example) this can lasts up to 60 seconds.
What I ended up doing was creating a WWW disposer that disposes WWWs when they are done; this prevents the device from freezing.
 public class WWWDisposer : MonoBehaviour
 {
     private List<WWW> m_wwwsToDispose = new List<WWW>();
 
     void Awake()
     {
         GameObject.DontDestroyOnLoad(gameObject);
     }
 
     public void AddWWWToDispose(WWW _toDispose)
     {
         m_wwwsToDispose.Add(_toDispose);
     }
 
     void Update()
     {
         for(int i = 0; i < m_wwwsToDispose.Count; i++)
         {
             if(m_wwwsToDispose[i].isDone)
             {
                 Debug.Log("[TRS] WWW disposed after natural error or completion: " + m_wwwsToDispose[i].url + ", " + m_wwwsToDispose[i].error);
                 m_wwwsToDispose[i].Dispose();
                 m_wwwsToDispose.RemoveAt(i);
                 i--;
             }
         }
     }
 
     public static WWWDisposer GetDisposer()
     {
         GameObject gameObject = GameObject.Find("_wwwDisposer");
         if(gameObject == null)
         {
             gameObject = new GameObject("_wwwDisposer");
             gameObject.AddComponent<WWWDisposer>();
         }
         return gameObject.GetComponent<WWWDisposer>();
     }
 }
 
               This is useful if you want to for example wait a maximum of 5 seconds to retrieve an asset from the server, if the request times out, you can use an embedded low res asset or a cached one.
Awesome, this fixed my Android Unity freezes upon inabilities to connect to the server. Thanks so much @peacefulshade
Answer by rutter · Oct 31, 2013 at 12:28 AM
I don't think you can override the default timeout, but remember that your coroutine can yield on values other than the WWW. You could instead check each frame (or every X seconds) if the WWW isDone.
If the WWW doesn't finish within whatever time limit you track, your coroutine can do something to handle that appropriately.
I ended up using Abacus's code from here to do that, and it seems to work...mostly. This still seems like a fairly messy process.
http://forum.unity3d.com/threads/36065-How-to-stop-the-www-request
Your answer