diff --git a/src/Websocket.Client/ResponseMessage.cs b/src/Websocket.Client/ResponseMessage.cs index c4ef4c0..ff1e0b9 100644 --- a/src/Websocket.Client/ResponseMessage.cs +++ b/src/Websocket.Client/ResponseMessage.cs @@ -1,4 +1,5 @@ -using System.Net.WebSockets; +using System; +using System.Net.WebSockets; namespace Websocket.Client { @@ -7,22 +8,43 @@ namespace Websocket.Client /// public class ResponseMessage { +#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER + private ResponseMessage(ref Memory binaryMemory, string text, WebSocketMessageType messageType) + { + BinaryMemory = binaryMemory; + Text = text; + MessageType = messageType; + } +#else private ResponseMessage(byte[] binary, string text, WebSocketMessageType messageType) { Binary = binary; Text = text; MessageType = messageType; } +#endif /// /// Received text message (only if type = WebSocketMessageType.Text) /// public string Text { get; } +#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER + /// + /// Received text message (only if type = WebSocketMessageType.Binary) + /// + public byte[] Binary => BinaryMemory.ToArray(); + + /// + /// Memory representation of the binary message + /// + public ReadOnlyMemory BinaryMemory { get; } +#else /// /// Received text message (only if type = WebSocketMessageType.Binary) /// public byte[] Binary { get; } +#endif /// /// Current message type (Text or Binary) @@ -42,6 +64,24 @@ public override string ToString() return $"Type binary, length: {Binary?.Length}"; } +#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER + /// + /// Create text response message + /// + public static ResponseMessage TextMessage(string data) + { + var emptyMemory = Memory.Empty; + return new ResponseMessage(ref emptyMemory, data, WebSocketMessageType.Text); + } + + /// s + /// Create binary response message + /// + public static ResponseMessage BinaryMessage(ref Memory data) + { + return new ResponseMessage(ref data, null, WebSocketMessageType.Binary); + } +#else /// /// Create text response message /// @@ -57,5 +97,6 @@ public static ResponseMessage BinaryMessage(byte[] data) { return new ResponseMessage(data, null, WebSocketMessageType.Binary); } +#endif } } \ No newline at end of file diff --git a/src/Websocket.Client/Websocket.Client.csproj b/src/Websocket.Client/Websocket.Client.csproj index 386bcbe..b8ce297 100644 --- a/src/Websocket.Client/Websocket.Client.csproj +++ b/src/Websocket.Client/Websocket.Client.csproj @@ -31,6 +31,7 @@ all runtime; build; native; contentfiles; analyzers + diff --git a/src/Websocket.Client/WebsocketClient.cs b/src/Websocket.Client/WebsocketClient.cs index 1318777..04bf674 100644 --- a/src/Websocket.Client/WebsocketClient.cs +++ b/src/Websocket.Client/WebsocketClient.cs @@ -1,3 +1,4 @@ +using Microsoft.IO; using System; using System.Diagnostics; using System.IO; @@ -24,6 +25,7 @@ public partial class WebsocketClient : IWebsocketClient private readonly WebsocketAsyncLock _locker = new WebsocketAsyncLock(); private readonly Func> _connectionFactory; + private static readonly RecyclableMemoryStreamManager _memoryStreamManager = new RecyclableMemoryStreamManager(); private Uri _url; private Timer _lastChanceTimer; @@ -450,7 +452,7 @@ private async Task Listen(WebSocket client, CancellationToken token) if (ms == null) { // create memory stream and insert first chunk - ms = new MemoryStream(); + ms = _memoryStreamManager.GetStream(); ms.Write(resultArrayWithTrailing, 0, resultArraySize); } @@ -522,12 +524,22 @@ await StopInternal(client, WebSocketCloseStatus.NormalClosure, "Closing", { if (ms != null) { +#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER + var binaryMemory = ms.ToArray().AsMemory(); + message = ResponseMessage.BinaryMessage(ref binaryMemory); +#else message = ResponseMessage.BinaryMessage(ms.ToArray()); +#endif } else { Array.Resize(ref resultArrayWithTrailing, resultArraySize); +#if NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER + var binaryMemory = resultArrayWithTrailing.AsMemory(); + message = ResponseMessage.BinaryMessage(ref binaryMemory); +#else message = ResponseMessage.BinaryMessage(resultArrayWithTrailing); +#endif } }