了解asp.net中的websockets

ca1c2owp  于 2024-01-09  发布在  .NET
关注(0)|答案(1)|浏览(137)

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

  1. var payload = new byte[FRAME_SIZE];
  2. var receivedFrame = await websocket.ReceiveAsync(payload, CancellationToken.None);
  3. while (!receivedFrame.EndOfMessage)
  4. {
  5. var frame = new byte[FRAME_SIZE]; // which is 8192
  6. receivedFrame = await websocket.ReceiveAsync(frame, CancellationToken.None);
  7. var nextBuffer = new byte[payload.Length + receivedFrame.Count];
  8. Array.Copy(payload, 0, nextBuffer, 0, payload.Length);
  9. Array.Copy(frame, 0, nextBuffer, payload.Length, receivedFrame.Count);
  10. payload = nextBuffer;
  11. }

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

sdnqo3pr

sdnqo3pr1#

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

  1. var buffer = new byte[FRAME_SIZE];
  2. var received = await webSocket.ReceiveAsync(buffer.AsMemory(), default);
  3. var totalBytes = received.Count;
  4. while (!received.EndOfMessage) {
  5. if (buffer.Length < totalBytes + FRAME_SIZE) {
  6. Array.Resize(ref buffer, buffer.Length * 2);
  7. }
  8. received = await webSocket.ReceiveAsync(buffer.AsMemory(totalBytes..), default);
  9. totalBytes += received.Count;
  10. }
  11. var result = buffer.AsMemory(..totalBytes);

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

展开查看全部

相关问题