2

我正在尝试打开与将定期通过 JSON 对象发送的 URL 的连接。我知道我需要使用 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 终止

4

1 回答 1

1

我试图理解你的问题。如果以下解释与您的不同,请忽略它。

这在协议缓冲方面有点低级。可能有第三方库可用于在 as3 上传输 json,您可以使用它们(例如:http ://code.google.com/p/as3corelib等)

您在客户端收到的数据可能是分块的,或者您可能一次获得所有数据。因此,为了跟踪数据大小(您收到的数据量),您需要知道服务器正在发送的数据大小。为此,我们通常将数据的前几个字节(通常为 4 个字节)编码为完整数据的大小。这可能会根据客户端和服务器都同意的协议而改变。

Data = "<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);
                    }                       
            }
于 2010-06-27T05:41:14.567 回答