diff --git a/src/OpenAPI.Net/OpenAPI.Net.csproj b/src/OpenAPI.Net/OpenAPI.Net.csproj index f6b3c39..9e67c02 100644 --- a/src/OpenAPI.Net/OpenAPI.Net.csproj +++ b/src/OpenAPI.Net/OpenAPI.Net.csproj @@ -9,7 +9,7 @@ cTrader, Open API, Spotware, cTrader A .NET RX library for cTrader Open API cTrader.OpenAPI.Net - 1.4.0 + 1.4.1 AnyCPU Spotware Spotware diff --git a/src/OpenAPI.Net/OpenClient.cs b/src/OpenAPI.Net/OpenClient.cs index ab67b22..7bb45ab 100644 --- a/src/OpenAPI.Net/OpenClient.cs +++ b/src/OpenAPI.Net/OpenClient.cs @@ -377,32 +377,29 @@ private async Task StartSendingMessages(CancellationToken cancellationToken) /// Task private async void ReadTcp(CancellationToken cancellationToken) { - var lengthArray = new byte[sizeof(int)]; + var dataLength = new byte[4]; try { while (!IsDisposed) { - var readBytes = 0; do { - var count = lengthArray.Length - readBytes; + var count = dataLength.Length - readBytes; - readBytes += await _sslStream.ReadAsync(lengthArray, readBytes, count, cancellationToken).ConfigureAwait(false); + readBytes += await _sslStream.ReadAsync(dataLength, readBytes, count, cancellationToken).ConfigureAwait(false); - if (readBytes == 0) new InvalidOperationException("Remote host closed the connection"); + if (readBytes == 0) throw new InvalidOperationException("Remote host closed the connection"); } - while (readBytes < lengthArray.Length); - - Array.Reverse(lengthArray); + while (readBytes < dataLength.Length); - var length = BitConverter.ToInt32(lengthArray, 0); + var length = GetLength(dataLength); if (length <= 0) continue; - var data = ArrayPool.Shared.Rent(length); + var data = new byte[length]; readBytes = 0; @@ -412,20 +409,15 @@ private async void ReadTcp(CancellationToken cancellationToken) readBytes += await _sslStream.ReadAsync(data, readBytes, count, cancellationToken).ConfigureAwait(false); - if (readBytes == 0) new InvalidOperationException("Remote host closed the connection"); + if (readBytes == 0) throw new InvalidOperationException("Remote host closed the connection"); } while (readBytes < length); var message = ProtoMessage.Parser.ParseFrom(data, 0, length); - ArrayPool.Shared.Return(data); - OnNext(message); } } - catch (Exception ex) when (ex is OperationCanceledException) - { - } catch (Exception ex) { var exception = new ReceiveException(ex); @@ -434,6 +426,20 @@ private async void ReadTcp(CancellationToken cancellationToken) } } + /// + /// Returns the length of a received message without causing extra allocation + /// + /// The byte arrary of received lenght data + /// int + private int GetLength(byte[] lengthBytes) + { + var lengthSpan = lengthBytes.AsSpan(); + + lengthSpan.Reverse(); + + return BitConverter.ToInt32(lengthSpan); + } + /// /// Writes the message bytes to TCP stream ///