如何将websocket连接解码为json流? [英] How to decode websocket connect as a json stream?

查看:621
本文介绍了如何将websocket连接解码为json流?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的客户端正在连接到Websocket服务器,并且所有通信均为json格式.我使用 ClientWebSocket 及其

My client is connecting to a websocket server and the communications are all in json format. I use the ClientWebSocket and its ReceiveAsync method as documented. My read loop is something like this:

byte[] data = new byte[4096];
ArraySegment<byte> buffer = new ArraySegment<byte>(data);
readLoopTask = Task.Run(async () =>
{
    while (true)
    {
        var result = await socket.ReceiveAsync(buffer, CancellationToken.None);
        if (result.Count > 0)
        {
            string m = Encoding.ASCII.GetString(data, 0, result.Count);
            ProcessMessage(m); // decode json string
        }
        else
        {
            Console.WriteLine("recved zero:", result);
            break;
        }
    }
}, token);

我发现此实现的问题是服务器传递的一些json对象很大,并且不适合缓冲区,在这种情况下,读取的输入将被截断并且不是有效的json字符串,因此解码失败.

The problems I found with this implementation is that some json objects the server passed is very big and it won't fit into the buffer, in that case the read input is truncated and is not a valid json string, so the decode fails.

有人认为我可以继续阅读websocket,直到读取完整的json对象,但这将导致非常复杂的解决方案,并且需要手动处理json字符串,因为我将不得不检查每个字节并搜索末尾json字符串.之后,我还需要保留该部分,因为它是下一个json对象的开始部分.

One could argue that I could continue reading the websocket until a complete json object is read, but that would result a very complex solution and requires handling of json string manually because I will have to check each byte and search for the end of json string. I will also need to preserve the part after that because it is the beginning part of next json object.

我的问题是,为什么WebSocket不会将其网络流导出到用户,就像

My question is that why WebSocket does not have its network stream exported to users, just like what TcpClient.GetStream does, in the TcpClient case, it will be very easy to handle this kind of situation, just supply the stream to a json decoder:

Stream stream = tcpClient.GetStream();
JsonDecoder decoder = new JsonDecoder(stream);
Object obj;
while (true) {
    decoder.Decode(obj);
    // handle obj
}

因此,鉴于目前尚不存在这样的API,有没有更好的方法来解决此问题?

So is there better way to solve this problem given that such a API is not available currently?

推荐答案

好,终于发现这不是要担心的问题.关键是ClientWebSocket.ReceiveAsync会返回一个WebSocketReceiveResult,它具有EndOfMessage,它是一个布尔型标志,指示这部分数据是否是消息的结尾,因此通常的操作将连续接收,直到该标志为true ,然后将所有累积的数据输入json解码器.

Ok, finally found this is not a question to worry about. The key is ClientWebSocket.ReceiveAsync will return a WebSocketReceiveResult, which has EndOfMessage, it is a Boolean flag to indicate whether this part of data is the end of a message, so the usual operation is receive continuously until the flag is true, then feed all the accumulated data into json decoder.

WebSocketReceiveResult result = null;
while(running) {
    do {
        result = await socket.ReceiveAsync(buffer, cts.Token).ConfigureAwait(false);
        if (result.Count > 0)
        {
             memStream.Write(buffer.Array, buffer.Offset, result.Count);
        }
        else
        {
             logger.LogWarning("WS recved zero: {0}, {1}", result.Count, socket.State);
             break;
        }
    } while (!result.EndOfMessage); // check end of message mark
}

这篇关于如何将websocket连接解码为json流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆