|
2 | 2 | using Microsoft.Extensions.Logging.Abstractions; |
3 | 3 | using Microsoft.IO; |
4 | 4 | using System; |
| 5 | +using System.Buffers; |
5 | 6 | using System.IO; |
6 | 7 | using System.Net.WebSockets; |
7 | 8 | using System.Reactive.Linq; |
@@ -483,30 +484,29 @@ private async Task Listen(WebSocket client, CancellationToken token) |
483 | 484 | { |
484 | 485 | // define buffer here and reuse, to avoid more allocation |
485 | 486 | const int chunkSize = 1024 * 4; |
486 | | - var buffer = new Memory<byte>(new byte[chunkSize]); |
| 487 | + // allocate bigger buffer (16kb) to avoid resizing in case of big messages |
| 488 | + var arrayBufferWriter = new ArrayBufferWriter<byte>(chunkSize * 4); |
487 | 489 |
|
488 | 490 | do |
489 | 491 | { |
490 | 492 | ValueWebSocketReceiveResult result; |
491 | | - var ms = MemoryStreamManager.GetStream(); |
492 | 493 |
|
493 | 494 | while (true) |
494 | 495 | { |
| 496 | + var buffer = arrayBufferWriter.GetMemory(chunkSize); |
495 | 497 | result = await client.ReceiveAsync(buffer, token); |
496 | | - ms.Write(buffer[..result.Count].Span); |
| 498 | + |
| 499 | + arrayBufferWriter.Advance(result.Count); |
497 | 500 |
|
498 | 501 | if (result.EndOfMessage) |
499 | 502 | break; |
500 | 503 | } |
501 | 504 |
|
502 | | - ms.Seek(0, SeekOrigin.Begin); |
503 | | - |
504 | 505 | ResponseMessage message; |
505 | | - bool shouldDisposeStream = true; |
506 | 506 |
|
507 | 507 | if (result.MessageType == WebSocketMessageType.Text && IsTextMessageConversionEnabled) |
508 | 508 | { |
509 | | - var data = GetEncoding().GetString(ms.GetBuffer(), 0, (int)ms.Length); |
| 509 | + var data = GetEncoding().GetString(arrayBufferWriter.WrittenSpan); |
510 | 510 | message = ResponseMessage.TextMessage(data); |
511 | 511 | } |
512 | 512 | else if (result.MessageType == WebSocketMessageType.Close) |
@@ -546,17 +546,17 @@ private async Task Listen(WebSocket client, CancellationToken token) |
546 | 546 | { |
547 | 547 | if (IsStreamDisposedAutomatically) |
548 | 548 | { |
549 | | - message = ResponseMessage.BinaryMessage(ms.ToArray()); |
| 549 | + message = ResponseMessage.BinaryMessage(arrayBufferWriter.WrittenSpan.ToArray()); |
550 | 550 | } |
551 | 551 | else |
552 | 552 | { |
553 | | - message = ResponseMessage.BinaryStreamMessage(ms); |
554 | | - shouldDisposeStream = false; |
| 553 | + var stream = MemoryStreamManager.GetStream(arrayBufferWriter.WrittenSpan); |
| 554 | + message = ResponseMessage.BinaryStreamMessage(stream); |
555 | 555 | } |
556 | 556 | } |
557 | 557 |
|
558 | | - if (shouldDisposeStream) |
559 | | - ms.Dispose(); |
| 558 | + // clear buffer for next message |
| 559 | + arrayBufferWriter.Clear(); |
560 | 560 |
|
561 | 561 | _logger.LogTrace(L("Received: {message}"), Name, message); |
562 | 562 | _lastReceivedMsg = DateTime.UtcNow; |
|
0 commit comments