gpt4 book ai didi

c# - 如何将 websocket 连接解码为 json 流?

转载 作者:太空狗 更新时间:2023-10-30 01:14:15 36 4
gpt4 key购买 nike

我的客户端正在连接到一个 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的情况下,有没有更好的方法来解决这个问题呢?

最佳答案

好吧,终于发现这不是一个值得担心的问题。关键是ClientWebSocket.ReceiveAsync会返回一个WebSocketReceiveResult,里面有EndOfMessage,是一个 bool 标志,表示这部分数据是不是消息结束,所以通常的操作是连续接收直到标志为真,然后将所有累积的数据提供给 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
}

关于c# - 如何将 websocket 连接解码为 json 流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44738862/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com