Длинный опрос с URLStream в ActionScript - как узнать, когда что-то делать с данными? - PullRequest
2 голосов
/ 27 июня 2010

Я пытаюсь открыть соединение с URL, который будет периодически отправлять через объект JSON.Я знаю, что мне нужно использовать URLStream и некоторые обратные вызовы событий, но я в неведении, когда узнаю, как «работают» потоки данных или общий поток операций.Предположим, я знаю, как открыть соединение и отправить правильные заголовки запроса.Во-первых, некоторый соответствующий код:

stream = new URLStream();
stream.addEventListener(ProgressEvent.PROGRESS, dataReceived);
stream.load(request);

private function dataReceived(pe:ProgressEvent):void
{
    //now what?
}

Если сервер выбрасывает объекты JSON, как мне узнать, чтобы остановить чтение одного завершенного объекта и передать его другой функции?Как часто вызывается dataReceived?Когда сервер что-то отправляет, он показывает, насколько велик JSON, чтобы вы знали, когда остановиться?После прочтения различных фрагментов кода из Интернета, я определил, что они будут основными участниками этой операции:

pe.bytesLoaded
stream.readUTFBytes (length: String)

и, возможно, pe.bytesTotal

Наверное, я не знаю, как использовать их вместе.Является ли bytesTotal ожидаемым полным размером входящего завершенного объекта JSON?Я так мало знаю об этом, я действительно не знаю, что спросить, так что я просто выкидываю вопросы там, ничего не понимая.Я читал http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/net/URLStream.html, но пример кода представляет собой скелет обратных вызовов, поэтому он бесполезен.

Надеюсь, я был ясен со своими вопросами, и спасибо!

Редактировать: одна запись JSON заканчивается переводом каретки \ r

1 Ответ

1 голос
/ 27 июня 2010

Я пытаюсь понять ваш вопрос. Если приведенное ниже объяснение отличается от вашего, просто проигнорируйте его.

Это немного низкий уровень буферизации протокола. Могут быть сторонние библиотеки, доступные для передачи json на as3 как таковые, вы можете использовать их (например: http://code.google.com/p/as3corelib и т. Д.)

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

Данные = "<4 байта> <Остальные данные>"

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

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

http://code.google.com/p/cave/source/browse/trunk/cave/wave/org/cestum/cave/presenter/rpc/CaveSocket.as

Я добавил комментарии для вашего понимания ...

               private function onResponse(e:ProgressEvent):void{
                    trace("Recieved Response");
                    //InputBuffer is socket buffer
                    if (inputBuffer.bytesAvailable == 0)
                            inputBuffer.clear();

                    //copy all bytes from socket buffer, to internal buffer - this way you avoid working on socket buffer internally
                    //and have more control on the pulling data your way. Because server keeps on appending data to socket buffer, 
                    //you may lose control
                    readBytes(inputBuffer, inputBuffer.length, bytesAvailable);

                    //AS3 is single threaded, we'll create a new event for our data 
                    //processing so that socket buffers its data from server seperately.
                    dispatchEvent(new Event("DataComplete"));
            }

            //DataComplete Event
            function onCompleteData(event:Event):void {
                    trace("Complete Data");
                    //We havent got the requires data size from server
                    if (requiredSize == -1) {
                            //Look for first four bytes - that has our data size.
                            if (inputBuffer.bytesAvailable < 4 ) {

                                    return;
                            }
                            var sizeBuffer:ByteArray = new ByteArray();
                            inputBuffer.readBytes(sizeBuffer,0 , 4);        
                            var ipStream1:CodedInputStream = CodedInputStream.newInstance(sizeBuffer);
                            requiredSize = ipStream1.readRawLittleEndian32();
                    }
                    if (requiredSize == -1) return;

                    trace( "Req: " + requiredSize + "   buffer_length: " + buffer.length  + "     bytes_Available: " + inputBuffer.bytesAvailable  + "     bytes_Position: " + inputBuffer.position);

                    //Now you know the size of data server is sending... just extract that amount of data from socket buffer to internal buffer.


                    if ((requiredSize - buffer.length) > inputBuffer.bytesAvailable) {
                            inputBuffer.readBytes(buffer,buffer.length , inputBuffer.bytesAvailable);
                            return;
                    } else {
                            inputBuffer.readBytes(buffer, buffer.length , (requiredSize - buffer.length));
                    }
                    trace("Before processing: " + buffer.length);

              ...Process your data here....


                    requiredSize = -1;
                    lastReadByte = -1;
                    buffer = new ByteArray();
                    if (inputBuffer.bytesAvailable > 0) {
                            onCompleteData(null);
                    }                       
            }
...