C# 为WebSocket响应选择缓冲区大小

C# 为WebSocket响应选择缓冲区大小,c#,json,websocket,buffer,clientwebsocket,C#,Json,Websocket,Buffer,Clientwebsocket,我正在编写一个C#应用程序,它连接到websocket服务器,并接收未知大小的JSON响应。我使用这个类就是为了这个目的 从客户端接收数据的唯一方法似乎是使用ReceiveAsync方法,该方法将ArraySegment作为参数: var client = new ClientWebSocket(); client.ConnectAsync(new Uri($"ws://localhost:{port}"), token).Wait(); var result = new ArraySegmen

我正在编写一个C#应用程序,它连接到websocket服务器,并接收未知大小的JSON响应。我使用这个类就是为了这个目的

从客户端接收数据的唯一方法似乎是使用
ReceiveAsync
方法,该方法将
ArraySegment
作为参数:

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();
var client=newclientwebsocket();
ConnectAsync(新Uri($“ws://localhost:{port}”),token.Wait();
var result=新的ArraySegment(新字节[1000]);
client.ReceiveAsync(result,token).Wait();
问题是,因为我不知道JSON响应会有多大,所以我不知道让ArraySegment的缓冲区支持多大。在本例中,我指定了1000字节,这太小了,响应被截断。但是,我担心如果我将缓冲区大小设置为任意大(1000000字节?),我将使用比需要更多的内存


如何在不知道响应大小的情况下选择缓冲区大小?

如果我正确理解API,它会在必要时将websocket消息分为多个部分提供给您

这意味着,如果从服务器发送的消息为2048字节,并且您使用1000字节的缓冲区,则执行以下操作:

var buffer = new ArraySegment<byte>(new byte[1000]);
var result = await client.ReceiveAsync(buffer, token);

当然,您还应该检查接收结果中的其他字段,如
MessageType

一个让我措手不及的观察结果:值结果。非EndOfMessage块的计数并不总是等于缓冲区大小。它可以更小。
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;
    }
}