Comet-style Long-Poll in AIR using URLStream
I'm attempting to connect to an existing Comet-style long-poll service using an AIR app. The service expects a client to make a GET request with a Connection: Keep-Alive header. This request will remain open for long periods of time so that the server can push data through. In my app, the connection is terminated with an IOError after 30 seconds.
Is this an undocumented limitation of URLStream? A restriction on adl (I've only been running my app through adl)?
The server does not send any "keep-alive" messages to the client but, unfortunately this is not something i have control over.
Update
To test this, I've set up a stripped-down version using a little php script (linked by leggetter below) and am hitting it from a simple AIR app. I'm finding that my connections are closed after 30 seconds whether I use URLStream or URLLoader. the PHP:
<?php
set_time_limit(0);
sleep(40);
echo("START!");
header('Content-type: text/plain');
echo str_pad('PADDING', 2048, '|PADDING');
$sleep_time = 1;
$count = 0;
while($count < 20) {
echo($count);
flush();
$count = $count + 1;
sleep($sleep_time);
}
echo("end");
?>
And the Actionscript:
private function beginSubscribeToNotifications():void {
var req:URLRequest = new URLRequest(myPHPFile);
req.method = URLRequestMethod.GET;
req.requestHeaders.push( new URLRequestHeader("Connection", "Keep-Alive"));
_urlLoader = new URLLoader();
_urlLoader.addEventListener(Event.COMPLETE, onComplete);
_urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
_urlLoader.load(req);
}
private functio开发者_运维百科n onComplete(e:Event):void {
_message = (String)(_urlLoader.data);
}
If i adjust the initial sleep time in the php script to anything over 30 seconds, the IOError event is triggered. If I lower the sleep time, but the request continues adding data past 30 seconds, the onComplete event is called, but _urlLoader.data is empty.
The only way this process completely successfully is if the entire thing is over before 30 seconds elapses.
Well, this is somewhat embarrassing, but I figured I'd post in case someone else runs in to this. I have solved my issue by setting the value of URLRequestDefaults.idleTimeout.
According to the documentation: When this property is set to 0 (the default), the runtime uses the default idle timeout value defined by the operating system. The default idle timeout value varies between operating systems (such as Mac OS, Linux, or Windows) and between operating system versions.
I guess for Windows 7 it was 30 seconds.
精彩评论