【问题标题】:How to decode websocket connect as a json stream?如何将 websocket 连接解码为 json 流?
【发布时间】:2017-11-28 01:30:04
【问题描述】:

我的客户端正在连接到 websocket 服务器,并且通信都是 json 格式。我使用ClientWebSocket 及其ReceiveAsync 方法,如文档所述。我的读取循环是这样的:

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字符串,所以解码失败。

有人可能会争辩说,我可以继续读取 websocket,直到读取完整的 json 对象,但这会导致非常复杂的解决方案,并且需要手动处理 json 字符串,因为我必须检查每个字节并搜索结尾json字符串。我还需要保留之后的部分,因为它是下一个 json 对象的开始部分。

我的问题是,为什么 WebSocket 没有将其网络流导出给用户,就像 TcpClient.GetStream 所做的那样,在 TcpClient 的情况下,处理这种情况会很容易,只需提供流到 json 解码器:

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

鉴于目前没有这样的 API,有没有更好的方法来解决这个问题?

【问题讨论】:

    标签: c# .net json websocket .net-core


    【解决方案1】:

    好的,终于发现这不是一个值得担心的问题。关键是ClientWebSocket.ReceiveAsync会返回一个WebSocketReceiveResult,里面有EndOfMessage,是一个布尔标志,表示这部分数据是否是消息的结尾,所以通常的操作是不断接收,直到标志为真,然后将所有累积的数据输入json解码器。

    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
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-18
      • 2018-07-26
      • 2021-11-05
      • 1970-01-01
      相关资源
      最近更新 更多