2012-02-13 2 views
3


Я делаю speedtest на AS3. И возникла такая проблема.
Я использую URLLoader() в своем тесте, и для загрузки тест работает очень хорошо, но для загрузки теста у меня возникли проблемы. Я отправляю некоторые двоичные данные на свой php-скрипт и проверяю progress_event, чтобы получить bytesLoaded, чтобы рассчитать текущую скорость, но событие не отправляется, появляется только complete_event, когда отправляется весь файл. Итак, как я могу определить скорость по методу отправки байтов?
AS3 Тест скорости загрузки

P.S. Я не могу использовать fileReference, потому что я использую свои тесты один за другим и не могу заставить пользователей щелкать в диалоговом окне filebrowse().

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 Мой PHP скрипт:

<? 
    $postdata = file_get_contents("php://input"); 
    file_put_contents("inp.bin",var_export($postdata,true)); 
    echo "Done"; 
    ?> 

Да, это мало, но я действительно не нужны данные, мне нужно, чтобы проверить, насколько быстро он загружен.

UPD 2

Итак, после прочтения всех ответов, комментариев и прибегая к помощи в течение нескольких часов, я, вероятно, получил решение, но это сделано в каком-то другом, чем я хочу в начале. В любом случае TYVM все, я отправлю решение в ближайшее время.

+0

где ваш код? вы должны установить прослушиватель событий с помощью 'addEventListener'. – vulkanino

+0

'_loader = new URLLoader(); _loader.dataFormat = URLLoaderDataFormat.BINARY; _loader.addEventListener (Event.COMPLETE, uploadComplete); _loader.addEventListener (ProgressEvent.PROGRESS, uploadProgress); ' все в порядке, событие просто не отправляется ... – Den

+0

Вы пытались отключить антивирусное программное обеспечение? см. Http://stackoverflow.com/questions/2930513/monitoring-file-upload-progress-in-actionscript-3 – Creynders

ответ

1

Попробуйте добавить это и посмотреть, есть ли у вас ошибка. Это может быть проблемой.

_loader.addEventListener("ioError", ldrError);  

function ldrError(evt:*):void 
{ 
    trace("ERROR"); 
} 

Возможно, проблема связана с вашим php-скриптом.

+0

Сначала я использую 'URLLoader' вместо' Loader' для работы с двоичными данными, а 'URLLoader' не имеет свойства' contentLoaderInfo'. И, наконец, я получил обработчик IOError, но он ничего не отслеживает. Таким образом, даже событие 'uploadComplete' отправляется после загрузки всех данных, но прогресс не выполняется. Я положу весь мой код, если сначала напишу. – Den

0

Возможно, я нашел его, не использую прилагаемый имитатор загрузки, загружаю/скачаю для реального, и он будет работать!

+0

Хороший звонок =) Но даже никакого результата. Я думаю, проблема заключается в том, что мой запрос POST отправляется «твердо» на сервер, а не по частям, поэтому отправляется только «Event.COMPLETE». Больше ничего. Я думаю, мне нужно использовать smthing как поток или другой способ вычисления скорости. – Den

+0

errrm, речь шла о SOCKET_DATA =). А для симулятора загрузки вы говорите? – Den

1

Вместо того, чтобы полагаться на ProgressEvent стрельбы, попробуйте добавить ENTER_FRAME слушателя и вытащить bytesLoaded из экземпляра _loader. Если работает ENTER_FRAME, вы можете попробовать заменить его с помощью повторяющегося TimerEvent на короткую задержку, чтобы уменьшить нагрузку на обработку ENTER_FRAME.

Я не могу проверить это прямо сейчас, но это должно по крайней мере дать вам знать, является ли проблема с ProgressEvent не срабатыванием или самой потоковой передачей.

+0

Спасибо. Я создал «TimerEvent», но есть проблема. 'bytesLoaded' возвращает количество ** полученных ** байтов, но мне нужно посчитать ** отправленные ** байты. – Den

+0

В ретроспективе это, очевидно, ожидаемое поведение. В этом случае я бы сказал, что вам придется выйти за пределы Flash. Я не уверен, что происходит в вашем скрипте PHP, но если загрузка действительно потоковая передача и сохранение на сервере во время загрузки (например, с FTP), то внутри вашего обработчика TimerEvent я бы опросил второй скрипт PHP который вызывает ** filesize() ** в потоковом файле и возвращает его во Flash. – DNJohnson

0

Любопытно, как быстро вы смогли протестировать в направлении загрузки и если у вас возникли проблемы с системами Windows? Кажется, что я сталкиваюсь с каким-то узким местом в системах Windows, используя различные браузеры, где моя загрузка достигает 25 Мбит/с. В системах Mac OS и Linux я получаю скорость линии ~ 100 Мбит/с.

+0

Загрузка в порядке, получение реальной скорости, почти равной результату speedtest.net. Подсчет полученных байтов в секунду. Это не вопрос. – Den

0

Звучит для меня как серверный скрипт, в нем есть ошибка. Это вернет ответ быстро, что не вызовет progressEvent.
В этом случае может вернуться что-то вроде кода ошибки blah blah blah в строке XX.
Подобный случай уволит полное событие, так как клиент получил ответ. (200 OK)


Вы подтвердили, что сценарий на стороне сервера в порядке?

+0

Да, все в порядке. И событие «complete» хорошо срабатывает, но это не то, что мне нужно. – Den

+0

Я все еще не продан, что вы понимаете, что я говорю. Вы отслеживали ответ с сервера и проверяли, что данные должны быть такими? Не предполагайте, потому что вы получили полное событие, что не было проблемы с сервером. –

+0

Речь идет о ** выгрузке ** части. Тест загрузки работает хорошо, прогресс запускается, байты подсчитываются. Но ** выгрузка ** часть нет. 'ProgressEvent' подсчитывает входящие байты, но мне нужно выйти. Да, есть способ получить скорость загрузки, например, «delta Time/totalBytes» в 'completeEvent', но мне нужно посчитать ее во время процесса загрузки динамически. – Den

0

Причина, по которой ваши события ProgressEvents не срабатывают, связана с тем, что они относятся к части вашего запроса (т. Е. Отклика с сервера), а не к части загрузки. Если ответ сервера был значительным (скажем, в виде большого изображения), вы наверняка увидите ProgressEvents, но поскольку ваш скрипт просто возвращает небольшой текст, он завершается очень быстро после завершения загрузки, прежде чем в любое время, когда URLLoader отправляет ProgressEvent.

Использование класса FileReference, как вы упомянули, является единственным способом, с помощью которого Flash может заглядывать в загружаемую версию, но, конечно, она имеет ряд ограничений.

Моей рекомендацией было бы настроить ваш URLLoader с полезной нагрузкой POST известного размера, а затем сохранить new Date().getTime() прямо перед вызовом метода загрузки. После возвращения COMPLETE снова получите текущее время и сравните, чтобы получить среднюю скорость загрузки, основанную на размере полезной нагрузки. Обратите внимание, что это приблизительное значение, поскольку оно неизбежно включает и часть загрузки, поэтому ваши расчетные скорости будут немного ниже, чем в действительности.

Другим обходным решением было бы следить за ходом и скоростью загрузки на серверной стороне и сообщать об этом, если Flash регулярно делает вызовы на отдельный сценарий выполнения загрузки до тех пор, пока все данные не будут переданы.