ActionScript 中的 URLStream 长轮询 - 如何知道何时对数据执行某些操作?

发布于 2024-09-07 17:40:10 字数 1021 浏览 6 评论 0原文

我正在尝试打开一个到 URL 的连接,该 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

I'm trying to open a connection to a URL that will periodically send over a JSON object. I know that I need to use URLStream and some event callbacks, but I'm in the dark when it comes to knowing how streams of data "work," or the general flow of operations. Assume I know how to open the connection and send the correct request headers. First, some relevant code:

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

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

If the server spurts out JSON objects, how do I know to stop reading one complete object and pass it to another function? How often is dataReceived called? When the server sends something over, does it give an indication how how big the JSON is so you know when to stop? After reading various snippets of code from around the internet, I've determined that these will be major players in this operation:

pe.bytesLoaded
stream.readUTFBytes(length:String)

and maybe pe.bytesTotal

I guess I don't know how to use them together. Is bytesTotal the total expected size of the incoming complete JSON object? I know so little about this I really don't know what to ask, so I'm just throwing questions out there in a clueless fashion. I've been reading http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/net/URLStream.html but the example code is a skeleton of callbacks so it isn't useful.

Hope I've been clear with my question(s), and thanks!

Edit: a single JSON entry is terminated with a carriage return \r

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

面犯桃花 2024-09-14 17:40:10

我正在尝试理解你的问题。如果下面的解释与你的解释有偏差,请忽略它。

这对于协议缓冲来说有点低级。可能有第三方库可用于在 as3 上传输 json,您可以使用它们(例如: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);
                    }                       
            }

I am trying to understand your question. If the below explanation deviates from yours, just ignore it.

This is a bit low-level on protocol buffering. There may be third party libraries available to transfer json on as3 as such, you can use them (Eg: http://code.google.com/p/as3corelib etc)

Data you receive at your client end may be chunk-ed or you may get all at once. So in-order to keep track of data size (amount of data you receive), you need to know the size of data server is sending. To do this, we generally code first few bytes (usually 4 bytes) of data with the size of complete data. This might change based on the protocol both client and server have agreed to.

Data = "<4 Bytes >< Rest of the data>"

So once you get the size of data the server is sending, you have to keep an internal buffer to collect the data until it receives the complete data.

I'll tell you how you can do this actionscript. This was taken from

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

I have added comments for your understanding...

               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);
                    }                       
            }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文