Mig*_*ell 6 c# buffer json websocket clientwebsocket
我正在编写一个连接到websocket服务器的C#应用程序,并收到一个未知大小的JSON响应.我正在ClientWebSocket为此目的使用该课程.
从客户端接收数据的唯一方法似乎是使用ReceiveAsync方法,该方法ArraySegment<byte>作为参数:
var client = new ClientWebSocket();
client.ConnectAsync(new Uri($"ws://localhost:{port}"), token).Wait();
var result = new ArraySegment<byte>(new byte[1000]);
client.ReceiveAsync(result, token).Wait();
Run Code Online (Sandbox Code Playgroud)
问题是,因为我不知道JSON响应有多大,我不知道缓冲区支持ArraySegment有多大.在这种情况下,我指定了1000个字节,这个字节太小了,并且响应被截断了.但是我担心如果我将缓冲区大小设置为任意大(1,000,000字节?),我将占用更多的内存而不是我需要的内存.
如何在不知道响应大小的情况下选择缓冲区大小?
如果我正确理解API,它将在必要时为您提供多个部分的websocket消息.
这意味着如果从服务器发送的消息是2048字节,并且您使用1024字节缓冲区并执行:
var buffer = new ArraySegment<byte>(new byte[1000]);
var result = await client.ReceiveAsync(buffer, token);
Run Code Online (Sandbox Code Playgroud)
然后在此第一个调用result.Count将设置为1000并将result.EndOfMessage设置为false.这意味着您需要继续读取,直到EndOfMessage设置为true,这意味着此示例为3次读取.
如果您需要一个缓冲区中的所有内容并且不能单独处理消息片段,则可以从一个小缓冲区开始,如果结果告诉您有更多数据进入,则调整接收缓冲区的大小.从而您也可以检查是否有超出最大尺寸接收停止.
int bufferSize = 1000;
var buffer = new byte[bufferSize];
var offset = 0;
var free = buffer.Length;
while (true)
{
var result = await client.ReceiveAsync(new ArraySegment<byte>(buffer, offset, free), token);
offset += result.Count;
free -= result.Count;
if (result.EndOfMessage) break;
if (free == 0)
{
// No free space
// Resize the outgoing buffer
var newSize = buffer.Length + bufferSize;
// Check if the new size exceeds a limit
// It should suit the data it receives
// This limit however has a max value of 2 billion bytes (2 GB)
if (newSize > maxFrameSize)
{
throw new Exception ("Maximum size exceeded");
}
var newBuffer = new byte[newSize];
Array.Copy(buffer, 0, newBuffer, 0, offset);
buffer = newBuffer;
free = buffer.Length - offset;
}
}
Run Code Online (Sandbox Code Playgroud)
当然,您还应该检查接收结果中的其他字段,例如MessageType.
| 归档时间: |
|
| 查看次数: |
4437 次 |
| 最近记录: |