views:

1232

answers:

6

Update: somehow this works when running flash in browser, but doesn't work if you run from IDE. You might want to try running in browser if you have the same problem.

I am making a chat application that repeatedly reads a text file from my server using Flash & Actionscript 3.0. I am opening the file with URLLoader, and it works fine at first. However after around 10 calls, the URLLoader gets stuck.

It does not give a completion event, does not give a security error, does not give a status event and does not throw an exception. It simply never fires any event at all. I even added a random value to the URL to make sure it is not some caching issue. I can detect when it gets stuck of course, but there doesn't seem to be any way to unstuck it. Even if I call close() on the URLLoader and then set it to null and create another one, it won't resume polling.

Below is the function that polls the server and gets called once every two seconds.

private function check_server() {
 var url:String = "http://coworkthailand.com/say/snd/index.php?"+Math.random();
 if (loader != null) {
  trace("was already checking "+loader.bytesLoaded+" / "+loader.bytesTotal);
  return;
 }
 loader =  new URLLoader();
 loader.dataFormat = URLLoaderDataFormat.TEXT;
 loader.addEventListener(Event.COMPLETE, completeHandler);
 loader.addEventListener(flash.events.IOErrorEvent.IO_ERROR, 
  function(e:Event) { loader = null; trace("fail"); })
 loader.addEventListener(flash.events.SecurityErrorEvent.SECURITY_ERROR, 
  function(e:Event) { loader = null; trace("security error"); })
 loader.addEventListener(flash.events.HTTPStatusEvent.HTTP_STATUS,
  function(e:flash.events.HTTPStatusEvent) { trace("status "+e.status); });
 try {
  loader.load(new URLRequest(url));
 } catch (error:Error) {
  trace("Unable to load requested document.");
 }
}

This is not an important project, but any ideas would be much appreciated!

A: 

I'm just guessing here, but perhaps the Flash Engine is blocked by the various parallel URLLoaders (if for some reason one gets stuck for a little bit more than two seconds, you already have two, etc.)

My idea is: use a single URLLoader. Set up the callbacks and event hooks in an init() funciton, and call load()`enter code here, and reuse the same instance every time you check the server for changes. That way, when the URLLoader is still busy, the new load request will either be ignored or it will cancel the previous one (not sure, which).

David Hanak
+1  A: 

For this scenario, best practice dictates using a single instance of URLLoader; chances are you're getting blocked somewhere by competing calls. As well, you might try using a simple flag to detect whether your loader's busy on an existing call before making another one; here's a working example using a single loader making requests every five seconds, showing both the single loader and the "isOpen" check:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="app_init()">    
    <mx:Script>
     <![CDATA[

      private var timer:Timer;
      private var loader:URLLoader;
      private var isOpen:Boolean;

      private function app_init():void
      {
       timer = new Timer(5000)
       timer.addEventListener(TimerEvent.TIMER, timer_tick, false, 0, true)

       loader = new URLLoader();
       loader.addEventListener(Event.OPEN, loader_open);
       loader.addEventListener(Event.COMPLETE, loader_complete);

       // Start the timer
       timer.start();
      }

      private function timer_tick(event:TimerEvent):void
      {
       // Check if the loader's busy before calling load, and/or close()
       if (!isOpen)
       {
        // loader.close();
        loader.load(new URLRequest("http://mydomain.com/myfile.txt"));
       } 
      }

      private function loader_open(event:Event):void
      {
       // Mark as open
       isOpen = true;
      }

      private function loader_complete(event:Event):void
      {
       // Do work

       // Mark as closed
       isOpen = false;
      }

     ]]>
    </mx:Script> 
</mx:Application>

Hope it helps! Good luck.

Christian Nunciato
A: 

It's also possible that your object is being cleaned up by the GC due to them not being connected to the main object graph.

Richard Szalay
No, that's not it. I use URLLoader's scoped and created within a method definition rather often, they always work smoothly.
David Hanak
A: 

It's also worth checking your HTTP traffic using Fiddler or Charles, it might help you get a better idea of what is going on.

Richard Szalay
A: 

I have the exact same problem. After 5 to 10 minutes flash consistently stops sending requests without throwing an exception, or other any other event being fired. And I am sure that no parallel URLoaders is the problem cause in my case only one is used. Did you manage to find a solution or any pointers towards one ?

+1  A: 

A browser usually allows only 2 simultaneous HTTP KeepAlive connections. The other connections are postponed.

Alexander Farber