了解asp.net中的websockets

ca1c2owp  于 11个月前  发布在  .NET
关注(0)|答案(1)|浏览(93)

据我所知,WebSocket的.ReceiveAsync方法的缓冲区大小是8192字节。如果我提供的缓冲区大小大于8192,它也可以工作。.net framework处理缓冲区的大小,还是自己处理它?
我想出了以下代码来处理大于8192字节的帧大小:

var payload = new byte[FRAME_SIZE];
    var receivedFrame = await websocket.ReceiveAsync(payload, CancellationToken.None);

    while (!receivedFrame.EndOfMessage)
    {
        var frame = new byte[FRAME_SIZE]; // which is 8192
        receivedFrame = await websocket.ReceiveAsync(frame, CancellationToken.None);

        var nextBuffer = new byte[payload.Length + receivedFrame.Count];

        Array.Copy(payload, 0, nextBuffer, 0, payload.Length);
        Array.Copy(frame, 0, nextBuffer, payload.Length, receivedFrame.Count);

        payload = nextBuffer;
    }

字符串
代码工作正常,但是当接收大于100 mb的数据时速度会很慢。将缓冲区大小设置为100 mb或更大会快得多。

sdnqo3pr

sdnqo3pr1#

考虑以下方法来减少分配和拷贝的数量:

var buffer = new byte[FRAME_SIZE];
var received = await webSocket.ReceiveAsync(buffer.AsMemory(), default);
var totalBytes = received.Count;

while (!received.EndOfMessage) {
    if (buffer.Length < totalBytes + FRAME_SIZE) {
        Array.Resize(ref buffer, buffer.Length * 2);
    }
    
    received = await webSocket.ReceiveAsync(buffer.AsMemory(totalBytes..), default);
    totalBytes += received.Count;
}

var result = buffer.AsMemory(..totalBytes);

字符串
代码未经测试。
一般的想法是从一个小的缓冲区开始,每次需要读取一个新帧时,缓冲区的大小都会增加一倍。因此,我们接收的帧越多,我们需要调整大小的频率就越低。Array.Resize()将负责分配和复制所需的内存。
此外,我们只使用一个缓冲区,我们不断写入,但对于每个ReceiveAsync()调用,我们开始写在前一个调用停止的缓冲区偏移。
最后,我们返回一个Memory<byte>视图,该视图覆盖了实际写入的负载缓冲区部分。根据您的代码,您可能希望使用Span<byte>/AsSpan()

相关问题