URLLoader stuck at Open event for long time - actionscript-3

My app loads an external URL (XML file) every 30 seconds. The app is set in startup so it starts whenever the system starts. The URLLoader stucks on the "open" event after every reboot of system. If I close the app and relaunch it, it works perfectly fine. I have added all event listeners on this URLLoader to see where is the problem. Every time it stuck at URLLoader open event. This is the straight forward code, does not seem to be any complexity. I have also tried exporting it with "Access network only" in publish settings.
private var liveFeedLoader:URLLoader = new URLLoader();
private var feedUpdateTimer:Timer = new Timer(30000);
private function init(e:Event):void {
liveFeedLoader.addEventListener(IOErrorEvent.IO_ERROR, liveFeedLoaderErrFx);
liveFeedLoader.addEventListener(Event.COMPLETE, liveFeedLoaderFx);
feedUpdateTimer.addEventListener(TimerEvent.TIMER, checkForUpdate);
liveFeedLoader.load(new URLRequest("https://s3-us-west-2.amazonaws.com/abcd/XYZ.xml"));
feedUpdateTimer.start();
}

Related

Actionscript 3 - Multiple navigateToURL() trigger multiple authorization popups

I have to execute multiple navigateToURL in an swf on file:// protocol (so I can't use ExternalInterface).
Unfortunately, I can't set this swf as trusted.
I am using this code:
var urls:Array = [
'file:///tmp/1',
'file:///tmp/2',
'file:///tmp/3'
];
var timer:Timer = new Timer(300, urls.length);
timer.addEventListener(TimerEvent.TIMER, onTimer);
function onTimer(e:TimerEvent):void {
navigateToURL(new URLRequest(urls[timer.currentCount - 1]), '_blank');
}
timer.start();
Unfortunately, now flash when navigateToURL() is used in an untrusted swf, ask for permissions in a popup like this
http://i.stack.imgur.com/pWQuB.jpg
with this code, this popup appears every time navigateToURL is executed, in my case 3 times, and it makes the program unusable. I thought flash was designed to ask for permissions just once.
There's a solution to avoid this behaviour?

Flash player stuck at Frame 1 after calling a function

I'm working in a flash CS6 and I'm having a trouble: After calling a function, player freezes at frame 1. This not happend during Ctrl+ENTER preview, but when I play the .swf file published (using flash player or opening it on a web browser, doesn't matter) is when the problem begin.
This is the code:
import flash.display.MovieClip;
var code:int = 0
var temp:int = 0;
var _xmlURL:String = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid=368335%20and%20u=%27c%27";
var _xmlData:XML;
function loadXML(xmlURL:String):void {
var loader:URLLoader = new URLLoader();
var request:URLRequest = new URLRequest(_xmlURL);
loader.load(request);
loader.addEventListener(Event.COMPLETE, loadData);
}
function loadData(event:Event):void{
_xmlData = new XML(event.currentTarget.data);
var dataG:XMLList = _xmlData.results.channel.item.elements();
code = dataG[5].#code;
temp = dataG[5].#temp;
trace(code);
trace(temp);
}
loadXML(_xmlURL);
I'm not used to use as3, I don't know if I'm using it right.
As you can see, the code reads an external xml file using "URLLoader" and its method ".load".
Thanks for your help.
BTW, I've already tried to play the published ".swf" file in other PCs (xp, seven, 8), one of them with Windows recently installed (seven).
Most likely (because you're loading in resources from the internet, and it works when you test), this has to do with the security settings of your application.
Go to your publish settings file -> publish settings.
You'll see a drop down labelled Local playback security. Ensure this is set to access network only and not the default acess local only.
This hangs up a lot of people when they first start using flash.
It's always good practice too, to listen not just for the COMPLETE event on your loaders, but also for error events such as:
loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandlerFunction);
loader.addEventListener(IOErrorEvent.NETWORK_ERROR, ioErrorHandlerFunction);
loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandlerFunction);
In your case, it's probably throwing a security error.

Google blocking Adobe Air network check at large scale

I have an Adobe Air desktop app that was used for an event recently that thousands of people used simultaneously started getting failed network checks when using google.com as a polling URL. Having each app checking every 3 seconds to that URL, about 10 minutes into the event every app started being redirected to a validation page on Google asking the user to prove they aren't a robot which obviously they couldn't see and therefore all users were told they had no internet. I am already using Akamai's Advanced Streaming plugin (which is based on OSMF [which uses NetStream]) for the video streaming. Is there a better way to check for a network connection (preferably just using the existing NetStream object).
Here is the existing code for the network monitor:
public function checkNetwork(url:String):void {
var urlRequest:URLRequest = new URLRequest(url);
urlRequest.method = "GET";
urlMonitor = new URLMonitor(urlRequest);
urlMonitor.addEventListener(StatusEvent.STATUS,onStatusChange);
urlMonitor.pollInterval = 3000;
urlMonitor.start();
}
private function onStatusChange(event:StatusEvent):void {
if(urlMonitor.available) {
isNetworkDown = false;
dispatchEvent(new Event("NetworkManager.NETWORK_UP"));
}
else {
isNetworkDown = true;
dispatchEvent(new Event("NetworkManager.NETWORK_DOWN"));
}
}
I don't think polling a remote URL is the best way to check for internet connectivity (At least every 3 seconds). AIR has the ability to check the network itself like so:
air.NativeApplication.nativeApplication.addEventListener(air.Event.NETWORK_CHANGE, onNetworkChange);
function onNetworkChange(event)
{
//Check resource availability
}
The Event.NETWORK_CHANGE event does not indicate a change in all
network activity, but only that a network connection has changed. AIR
does not attempt to interpret the meaning of the network change.
http://help.adobe.com/en_US/AIR/1.5/devappshtml/WS5b3ccc516d4fbf351e63e3d118666ade46-7fcc.html
With that said, I would put your polling request inside the onNetworkChange event that way it checks only when necessary.

Why does URLStream complete event get dispatched when the file is not finished loading?

I'm writing an AIR kiosk app that every night connects to a WordPress server, gets a JSON file with paths to all the content, and then downloads that content and saves it to the kiosk hard drive.
There's several hundred files (jpg, png, f4v, xml) and most of them download/save with no problems. However, there are two f4v files that never get downloaded completely. The complete event does get dispatched, but if I compare the bytesTotal (from the progress event) vs bytesAvailable (from the complete event) they don't match up; bytesTotal is larger. The bytesTotal (from the progress event) matches the bytes on the server.
The bytesLoaded in the progress event never increases to the point that it matches the bytesTotal either so I can't rely on the progress event either. This seems to happen on the same two videos every time. The videos are not very large, one is 13MB and the other is 46MB. I have larger videos that download without any problems.
EDIT: After rebooting my computer, the two videos now finish downloading but I'm getting the same problem with a 300kb png file.
If I paste the url into Firefox it downloads correctly. I've also written a simple c# app to download the files and it is able to download them with no problems, so it appears to be a problem with Flash/AIR.
EDIT: here's a simpler version of the code, this is from a test project and it's the only code (the url is on our local network so you won't be able to download the file yourself):
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.net.URLRequest;
import flash.net.URLStream;
[SWF(backgroundColor="#000000", frameRate="24", width="640", height="480")]
public class Test extends Sprite {
private var fileSize:Number;
private var stream : URLStream;
private var url:String = "http://192.168.150.219/wordpress2/wp-content/uploads/2012/12/John-Butler-clip1.f4v";
public function Test() {
if (stage)
init();
else
this.addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event=null):void {
this.removeEventListener(Event.ADDED_TO_STAGE, init);
stream = new URLStream();
stream.addEventListener(ProgressEvent.PROGRESS, onLoadProgress);
stream.addEventListener(Event.COMPLETE, onLoadComplete);
stream.load(new URLRequest(url));
}
private function onLoadProgress(event:ProgressEvent):void {
fileSize = event.bytesTotal;
var percent:Number = event.bytesLoaded / event.bytesTotal * 100;
trace(percent + "%"); // this never gets to 100%
}
private function onLoadComplete(event:Event):void {
trace("loaded", stream.bytesAvailable, "of", fileSize);
// outputs "loaded 13182905 of 13184365"
// so why is it "complete" when it isn't fully downloaded?
}
}
}
Don't compare to bytesAvailable, use length instead. BytesAvailable is actually ByteArray.length - ByteArray.position. So if the position within the ByteArray has moved away from index 0, the bytesAvailable value will decrease. Length will always be the total number of bytes within the array.
Try comparing using length and see if this makes any difference. I don't have time to sift through your code to see if you are changing position at any point (either purposefully or accidentally; you can do it in more ways than one), so that's the best I can offer right now.
If anyone else has the same problem like I did. It turned out to be a caching problem which is present in AIR as well so a timestamp added to the request solves this: http://www.newtonflash.com/blog/as3/prevent-xml-caching-problem/#comment-43
{
var xmlPath:String="replaceYourXMLPathHere.xml"
var urlReq:URLRequest = new URLRequest(xmlPath+"?time=" + new Date().getTime());
}
Your answer is in your question.
Normal URLs (files) - to this server this is a block of data. Once the server delivers the 'block of data' the delivery process is considered 'COMPLETE'. In this case if a file is 100kb, once the 100kb is received - Flash considers this as 'COMPLETE'.
URLStream - to the server this is [TWO] blocks of data (very simple way to look at it). The server will first serve the CONNECTION to the stream... then serve the STREAM DATA. This is handled in Flash just as its described.
Flash will consider the loading of the CONNECTION as 'COMPLETE', and NEVER check if the STREAM data is loaded - thats up to your server. In any streams you should actually check the [load progress] event and read each byte of data as it comes in... then construct as required.

Why Dispatching Event.OPEN Instead of IOErrorEvent.IO_ERROR?

Why does the load method of the URLStream class dispatch Event.OPEN instead of IOErrorEvent.IO_ERROR when the SWF is on a webserver and when trying to load an invalid URL?
The same doesn't apply when running the SWF locally.
Sample code:
var CLS_UrlStream:URLStream = new URLStream(); // Initialize URLStream class instance.
CLS_UrlStream.addEventListener(Event.OPEN, FUN_StreamHandler); // Listen for successful connections.
CLS_UrlStream.addEventListener(IOErrorEvent.IO_ERROR, FUN_StreamHandler); // Listen for conenction errors.
CLS_UrlStream.load(new URLRequest("InvalidURL")); // Load file.
private function FUN_StreamHandler(FUN_PAR_Event:Event):void {
trace("EVENT TYPE: " + FUN_PAR_Event.type);
}
// Outputs: EVENT TYPE: open
Event.OPEN gets triggered on load. So will always be called.
You probably want HTTPStatusEvent.HTTP_STATUS
When the SWF is running on the server and is requesting for a resource that doesn't exist, the server actually sends an error message which counts as data, thus there is no error event. The same didn't apply locally because there was no web server to respond with an error when a request for an nonexistent file is made. Discovered this by tracing live with the Monster Debugger.