IOError 2032 happens sometimes - actionscript-3

My application loads 60 files at the same time. I mean I create 60 loaders (in an array) and start all loadings in a loop, I don't wait for one to complete before I start the next.
I use a class that extends URLLoader to load xml, bin, png, mp3 and swf.
I log when users get a IOErrorEvent, and I see error 2032 happen sometimes, not always with the same file, and when I try again, the loading completes.
Do you know why I could have a random 2032 error with URLLoader ?
Edit : Is URLLoader appropriate to load many files at a time ? Should I better have an open connection, request all the files, then close the connection ?

It could be because of improper handling of Loader Events and data associated with it.
You can try using:
BulkLoader Class by Arthur Debert
they have done some reliable work in this regard.

Related

Why does URLStream sometimes not fire Event.COMPLETE?

I've got an application that is downloading several large binary files and saving them to disk. On some machines it works fine and on some other machines every once in a while a download will proceed to 99.9% complete and the URLStream object will not fire Event.COMPLETE
This is almost identical to the issue that appears here:
Why does URLStream complete event get dispatched when the file is not finished loading?
I've tried using the 'Cache Bust' method described in one of the answers but still no dice.
Any help would be appreciated.
Here is some sample code to help illustrate what I am trying to do:
var contentURL:String = "http://some-large-binary-file-in-amazon-s3.tar";
var stream:URLStream = new URLStream();
stream.addEventListener(Event.COMPLETE, function(e:Event):void{
//This should fire when the file is done downloading
//On some systems this fails to fire once in a while
//On other systems it never fails to fire
});
stream.addEventListener(ProgressEvent.PROGRESS, function(pe:ProgressEvent):void{
//Write the bytes available in the stream and save them to disk
//Note that a download will reach 100% complete in terms of total progress but the 'complete' event might still not fire.
});
var urlRequest:URLRequest = new URLRequest(contentURL);
//Here we might add some headers to the URL Request for resuming a file
//but they don't matter, the 'Event.COMPLETE' will fail to fire with our without
//these headers
addCustomHeaders( urlRequest );
stream.load( urlRequest );
Imo this is a code meant to fail where you purposely give up any control on whatever is going on and just assume that everything would work by itself and go well. I never had any problems whatsoever with the URLStream class but here's basically what I never do:
I never not register all the different error event available (you don't register any).
I never use anonymous listeners. Even though they are supposed to not be GC until the download is complete this is imo an unnecessary unsafe bet especially since it's not rare for the URLStream to idle a little while loading the last bits. I would not be surprised if removing those anonymous listeners would actually fix the problem.

Using URLStream to load part of a file

When loading a file using a URLStream (or a URLLoader) is there any way to specify a range of bytes to load instead of loading the entire file in to memory?
This is kind of a broad question because of nuances. The short answer is No, loading URLs will give you the complete resource.
The longer answer:
URLLoader - No; it loads the complete resource. You do get progress events which tell you how much of the file has been loaded.
URLStream - Maybe; it makes data available in chunks as it is loaded. You can close the stream before it finishes downloading if the data you care about is at the beginning of the file. Note that the data is in raw binary form.
Revisit URLLoader - Maybe; you could write a server that takes a beginIndex and an endIndex, then call URLLoader.load('http://my-server/file?beginIndex=' + desiredBeginIndex + '&endIndex=' + desiredEndIndex);
You'll end up with only the portion of the file that you care about if you have a way of knowing which indices to specify.
...mmm... You could load and track the number of bytes. Then, when you've reached your desired number of bytes loaded, do a loader.close()... (Tracking and saving them with a progress event, a byte array, and a global number var)
I dont know about getting data from the middle though, but you can load any range of bytes from the beginning using that method.
Loader.close()
Closes the load operation in progress. Any load operation in progress is immediately terminated. If no URL is currently being streamed, an invalid stream error is thrown.

Catch a loader error and try reloading

I am wondering if my code will work for catching a load error and if it is safe to attempt a reload. Since it is loading from my server I am assuming all files exist and the load error is just "something going wrong with networking".
m_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoaderComplete);
m_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, LoaderError);
m_loader.load(new URLRequest("MyFile.png"));
private function LoaderError(e:Event):void
{
//Try to reload
m_loader.load(new URLRequest("MyFile.png"));
}
My two questions are as follows
1) Will IOErrorEvent.IO_ERROR catch all of the possible networking errors that can happen when downloading a file.
2) Is it okay to just attempt another reload?
Thanks in advance.
1 - Yes it will catch most network errors, you might also want to check SecurityErrorEvent.SECURITY_ERROR but that probably will happen all the time if you don't have a proper crossdomain.xml file
2 - It is okay to attempt another reload but that might fail too, what I usually do is try to reload once and if that fails use a default image that I created in code. This way your program can still function even if it fails to load some images due to network problems.

URLLoader does not resond to .close()

My application requires that I am able to abort/close a URLLoader instance at any point in the post-connect stage; that is, regardless if I have connected and the file transfer has already begun, or whether I have connected, and the file transfer has yet to commence (the server has not begun sending the file yet).
Here is my code:
var myTextLoader:URLLoader = new URLLoader();
myTextLoader.load(new URLRequest("myText.txt"));
This is what I have noticed:
When I connect to a server, and the server starts sending the file immediately, DURING the actual file transfer, if I invoke myTextLoader.close(), it aborts immediately. This is expected. I can monitor this by executing the SWF in Firefox,and noticing that when I issue the close(), the network connecion goes from Pending to aborted.
However, if I connect to the server, and the file transfer has not actually begun yet (I have confirmed the connect event has fired, and the server has simply not begun sending the file), then myTextLoader.close() has no effect. Only AFTER the first bytes start being transferred from the server, will .close() have any effect. I can verify the connection is stuck in Pending in Firebug.. .close() has no effect until the transfer has started.
Any ideas how to work around this issue? I need to be able to invoke .close() and have the connection torn down regardless of the connection stage.
First thing I would think of, is create a bool "aborted" that is set to true where the close() method is invoked.
Like :
function abort():void {
_aborted = true;
myTextLoader.close();
}
Then check for its value anywhere in the onProgress event or any similar event, to actually call the URLLoader close() method again whenever its value is true...
function onProgress(evt:ProgressEvent):void {
if (_aborted) {
myTextLoader.close();
}
}
Its not a pretty thing and is an ugly workaround, but this could work, since when the first bits are actually received, you'll know if you already wanted to close it or not.
Did you find any bug report on that anywhere ?... I doubt it could be an intended behavior...
3rd party AS3 HTTPClient (https://github.com/gabriel/as3httpclient) appears to not exhibit this issue with close().

How to detect the presense of an SWF in the browser cache?

I have an AS3 application that loads various SWFs at runtime. The loading animation that is being used has a fairly long in and out animation that I don't want to show if the target SWF is in the browser cache.
So at the moment each SWF is loaded in as required using Greensock's SWFLoader in a basic manner:
var context:LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;
loader = new SWFLoader("mySWF.swf", {name:"sectionLoader",context:context,auditSize:true,onOpen:onLoadInit,onProgress:onLoadProgress, onComplete:onCompleteLoadHandler, onError:onLoadErrorHandler});
loader.load();
My goal is to do something before calling loader.load(); to determine if the load operation will require the request to go beyond the browser cache, but before I get into R&Ding something I thought I'd ask if anyone has already done something similar.
A few more thoughts I've had so far:
Just keeping track of what has been loaded in AS3 isn't good enough because if the user clears their cache they might be left loading a large SWF on a slow connection with no indicator.
Might a combination of LoaderItem.httpStatus and LoaderItem.auditSize() be worth investigating?
Is there a better loading framework for AS3 that I should be looking into instead of the Greensock classes?
Ideally I would prefer to also have some kind of version detection to span sessions that could be months apart, but one step at a time.
when you are doing any HTTP request, the responce comes up with HTTPStatus property. In AS3 you just need to chek if
HttpStatusEvent.status == 304
And for httpStatus in greensock library.
Basically 304 code means that no chages has been made on server side to the resource which user has requested. Which eventually leads to conclution that the resource is in the cache.
UPDATE
If this will not fit your needs try storing some variable for should you play the animation or not in Cookies or in Session variables.