Reputation: 601
I'm making an speedtest on AS3. And got such a problem.
I'm using URLLoader( )
in my test, and for download test it work very good, but for uploading test i got some troubles. I'm sending some binary data to my php-script, and checking the progress_event
to get bytesLoaded
, to calculate current speed, but the event is not dispatching, only complete_event
appears when thi whole file is sent. So how can I determine the speed by bytes-sending process?
P.S. I can't use fileReference
, cause I'm using my tests one-by-one and can't make users click in filebrowse() dialog.
Thx.
public function startme( ):void {
_startTime = ( new Date( ) ).getTime( );
var req:URLRequest = new URLRequest();
req.url = "http://smart.t3a.ru/speedtest/test.php";
req.contentType = 'application/octet-stream';
req.method = URLRequestMethod.POST;
req.data = Obj;
//req.requestHeaders.push( new URLRequestHeader( 'Cache-Control', 'no-cache' ) );
_loader = new URLLoader();
_loader.dataFormat = URLLoaderDataFormat.BINARY;
_loader.addEventListener(Event.COMPLETE,uploadComplete);
_loader.addEventListener(ProgressEvent.PROGRESS, uploadProgress );
_loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onstatus);
_loader.addEventListener(IOErrorEvent.IO_ERROR, eIOError);
_loader.load(req);
}
private function onstatus(event:HTTPStatusEvent):void
{
trace(event);
}
private function eIOError(event:IOErrorEvent):void
{
trace(event);
}
private function uploadComplete( e:Event ):void
{
var endTime:Number = ( new Date( ) ).getTime( );
var totalTime:Number = ( endTime - _startTime ) / 1000;
var totalKB:Number = Obj.length * 8 / 1024;
//_speed = totalKB / totalTime;
if (debug)
{
trace( "U total time: " + totalTime + " total KB: " + totalKB + " speed: " + speed + "KBps" );
}
dispatchEvent( e );
}
private function uploadProgress( e:ProgressEvent ):void
{
var endTime:Number = ( new Date( ) ).getTime( );
var totalTime:Number = ( endTime - _startTime ) / 1000;
if (totalTime > 1)
{
var totalKB:Number = e.bytesLoaded * 8 / 1024;
_speed = totalKB / totalTime;
if (debug)
{
trace( "u total time: " + totalTime + " total KB: " + totalKB + " speed: " + speed + "KBps" );
}
dispatchEvent( e );
}
if (totalTime > 7)
{
var ec:Event = new Event(Event.COMPLETE);
_loader.dispatchEvent(ec);
_loader.close();
}
}
UPD My php script:
<?
$postdata = file_get_contents("php://input");
file_put_contents("inp.bin",var_export($postdata,true));
echo "Done";
?>
Yes it's small, but i realy don't need the data, i need to check how fast is it uploaded.
UPD 2
So, after reading all the answers, comments and googling for hours, i probably got the solution, but it is made in some different way, than i wish at the beginning. Anyway TYVM all, i'll post the solution shortly.
Upvotes: 3
Views: 1583
Reputation: 604
The reason your ProgressEvents aren't firing is because they pertain to the download portion of your request (i.e. the response from the server), and not the upload portion. If the server response had been sizable (say, in the form of a large image), you'd certainly see ProgressEvents, but because your script is just returning a small amount of text, it completes very quickly after the upload finishes, before there is any time for the URLLoader to dispatch a ProgressEvent.
Using the FileReference class, as you mentioned, is the only way Flash can introspect on an upload that's underway, but of course it comes with a number of limitations.
My advice would be to set up your URLLoader with a POST payload of a known size, and then store new Date().getTime()
right before calling the load method. Once the COMPLETE event is returned, get the current time again, and compare to get an average upload rate based on the size of the payload. Note that this is only approximate because it inevitably incorporates the download portion too, so your calculated speeds will be slightly lower than in reality.
One other workaround would be to monitor the running progress and speed of an upload on the server side, and report this back by having Flash regularly make calls to a separate upload progress script, until the data has all been transferred.
Upvotes: 0
Reputation: 6402
Sounds to me like the server script has an error in it. Which would return a response fast that would not trigger the progressEvent.
In this case might return something like an error code blah blah blah on line XX.
A case like this would fire the complete event since the client did get a response. (200 OK)
Have you verified the server side script is ok?
Upvotes: 0
Reputation: 115
Was curious how fast you were able to test in the download direction and if you encountered any problems with Windows Systems? I seem to be hitting some sort of bottleneck in Windows systems using various browsers where my download maxes out at ~25Mbps. On Mac OS's and Linux systems, I'm hitting line speed of ~100Mbps.
Upvotes: 0
Reputation: 776
Instead of relying on the ProgressEvent firing, try adding an ENTER_FRAME listener and pull the bytesLoaded from the _loader instance. If the ENTER_FRAME works, you could then try replacing it with a repeating TimerEvent on a short delay to reduce the processing load of ENTER_FRAME.
I'm not able to test this right now but this should at least let you know if it's a problem with ProgressEvent not firing or the streaming itself.
Upvotes: 1
Reputation: 2677
Try to add this, and see if you are getting an error. That might be the problem.
_loader.addEventListener("ioError", ldrError);
function ldrError(evt:*):void
{
trace("ERROR");
}
It could be that there is a problem in your php script.
Upvotes: 1
Reputation: 9134
Maybe I've found it, don't use the included download simulator, upload/download for real and it will work!
Upvotes: 0