@@ -10,6 +10,7 @@ using MQTTnet.Core.Adapter; | |||||
using MQTTnet.Core.Diagnostics; | using MQTTnet.Core.Diagnostics; | ||||
using MQTTnet.Core.Serializer; | using MQTTnet.Core.Serializer; | ||||
using MQTTnet.Core.Server; | using MQTTnet.Core.Server; | ||||
using MQTTnet.Core.Channel; | |||||
namespace MQTTnet.Implementations | namespace MQTTnet.Implementations | ||||
{ | { | ||||
@@ -86,7 +87,7 @@ namespace MQTTnet.Implementations | |||||
try | try | ||||
{ | { | ||||
var clientSocket = await Task.Factory.FromAsync(_defaultEndpointSocket.BeginAccept, _defaultEndpointSocket.EndAccept, null).ConfigureAwait(false); | var clientSocket = await Task.Factory.FromAsync(_defaultEndpointSocket.BeginAccept, _defaultEndpointSocket.EndAccept, null).ConfigureAwait(false); | ||||
var clientAdapter = new MqttChannelCommunicationAdapter(new MqttTcpChannel(clientSocket, null), new MqttPacketSerializer()); | |||||
var clientAdapter = new MqttChannelCommunicationAdapter(new BufferedCommunicationChannel(new MqttTcpChannel(clientSocket, null)), new MqttPacketSerializer()); | |||||
ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(clientSocket.RemoteEndPoint.ToString(), clientAdapter)); | ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(clientSocket.RemoteEndPoint.ToString(), clientAdapter)); | ||||
} | } | ||||
catch (Exception exception) when (!(exception is ObjectDisposedException)) | catch (Exception exception) when (!(exception is ObjectDisposedException)) | ||||
@@ -93,17 +93,15 @@ namespace MQTTnet.Implementations | |||||
} | } | ||||
} | } | ||||
public async Task ReadAsync(byte[] buffer) | |||||
public async Task<ArraySegment<byte>> ReadAsync(int length, byte[] buffer) | |||||
{ | { | ||||
if (buffer == null) throw new ArgumentNullException(nameof(buffer)); | |||||
try | try | ||||
{ | { | ||||
var totalBytes = 0; | var totalBytes = 0; | ||||
do | do | ||||
{ | { | ||||
var read = await _dataStream.ReadAsync(buffer, totalBytes, buffer.Length - totalBytes).ConfigureAwait(false); | |||||
var read = await _dataStream.ReadAsync(buffer, totalBytes, length - totalBytes).ConfigureAwait(false); | |||||
if (read == 0) | if (read == 0) | ||||
{ | { | ||||
throw new MqttCommunicationException(new SocketException((int)SocketError.Disconnecting)); | throw new MqttCommunicationException(new SocketException((int)SocketError.Disconnecting)); | ||||
@@ -111,7 +109,8 @@ namespace MQTTnet.Implementations | |||||
totalBytes += read; | totalBytes += read; | ||||
} | } | ||||
while (totalBytes < buffer.Length); | |||||
while (totalBytes < length); | |||||
return new ArraySegment<byte>(buffer, 0, length); | |||||
} | } | ||||
catch (SocketException exception) | catch (SocketException exception) | ||||
{ | { | ||||
@@ -143,5 +142,10 @@ namespace MQTTnet.Implementations | |||||
return certificates; | return certificates; | ||||
} | } | ||||
public int Peek() | |||||
{ | |||||
return _socket.Available; | |||||
} | |||||
} | } | ||||
} | } |
@@ -11,9 +11,6 @@ namespace MQTTnet.Implementations | |||||
public sealed class MqttWebSocketChannel : IMqttCommunicationChannel, IDisposable | public sealed class MqttWebSocketChannel : IMqttCommunicationChannel, IDisposable | ||||
{ | { | ||||
private ClientWebSocket _webSocket = new ClientWebSocket(); | private ClientWebSocket _webSocket = new ClientWebSocket(); | ||||
private const int BufferSize = 4096; | |||||
private const int BufferAmplifier = 20; | |||||
private readonly byte[] WebSocketBuffer = new byte[BufferSize * BufferAmplifier]; | |||||
private int WebSocketBufferSize; | private int WebSocketBufferSize; | ||||
private int WebSocketBufferOffset; | private int WebSocketBufferOffset; | ||||
@@ -42,50 +39,39 @@ namespace MQTTnet.Implementations | |||||
_webSocket?.Dispose(); | _webSocket?.Dispose(); | ||||
} | } | ||||
public Task ReadAsync(byte[] buffer) | |||||
public async Task<ArraySegment<byte>> ReadAsync(int length, byte[] buffer) | |||||
{ | { | ||||
return Task.WhenAll(ReadToBufferAsync(buffer)); | |||||
await ReadToBufferAsync(length, buffer).ConfigureAwait(false); | |||||
var result = new ArraySegment<byte>(buffer, WebSocketBufferOffset, length); | |||||
WebSocketBufferSize -= length; | |||||
WebSocketBufferOffset += length; | |||||
return result; | |||||
} | } | ||||
private async Task ReadToBufferAsync(byte[] buffer) | |||||
private async Task ReadToBufferAsync(int length, byte[] buffer) | |||||
{ | { | ||||
var temporaryBuffer = new byte[BufferSize]; | |||||
var offset = 0; | |||||
if (WebSocketBufferSize > 0) | |||||
{ | |||||
return; | |||||
} | |||||
while (_webSocket.State == WebSocketState.Open) | |||||
var offset = 0; | |||||
while (_webSocket.State == WebSocketState.Open && WebSocketBufferSize < length) | |||||
{ | { | ||||
if (WebSocketBufferSize == 0) | |||||
WebSocketReceiveResult response; | |||||
do | |||||
{ | { | ||||
WebSocketBufferOffset = 0; | |||||
WebSocketReceiveResult response; | |||||
do | |||||
{ | |||||
response = await _webSocket.ReceiveAsync(new ArraySegment<byte>(temporaryBuffer), CancellationToken.None).ConfigureAwait(false); | |||||
temporaryBuffer.CopyTo(WebSocketBuffer, offset); | |||||
offset += response.Count; | |||||
temporaryBuffer = new byte[BufferSize]; | |||||
} while (!response.EndOfMessage); | |||||
response = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer, offset, buffer.Length - offset), CancellationToken.None).ConfigureAwait(false); | |||||
offset += response.Count; | |||||
} while (!response.EndOfMessage); | |||||
WebSocketBufferSize = response.Count; | |||||
if (response.MessageType == WebSocketMessageType.Close) | |||||
{ | |||||
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).ConfigureAwait(false); | |||||
} | |||||
Buffer.BlockCopy(WebSocketBuffer, 0, buffer, 0, buffer.Length); | |||||
WebSocketBufferSize -= buffer.Length; | |||||
WebSocketBufferOffset += buffer.Length; | |||||
} | |||||
else | |||||
WebSocketBufferSize = response.Count; | |||||
if (response.MessageType == WebSocketMessageType.Close) | |||||
{ | { | ||||
Buffer.BlockCopy(WebSocketBuffer, WebSocketBufferOffset, buffer, 0, buffer.Length); | |||||
WebSocketBufferSize -= buffer.Length; | |||||
WebSocketBufferOffset += buffer.Length; | |||||
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).ConfigureAwait(false); | |||||
} | } | ||||
return; | |||||
} | } | ||||
} | } | ||||
@@ -105,5 +91,10 @@ namespace MQTTnet.Implementations | |||||
throw new MqttCommunicationException(exception); | throw new MqttCommunicationException(exception); | ||||
} | } | ||||
} | } | ||||
public int Peek() | |||||
{ | |||||
return WebSocketBufferSize; | |||||
} | |||||
} | } | ||||
} | } |
@@ -22,7 +22,7 @@ namespace MQTTnet | |||||
{ | { | ||||
case MqttConnectionType.Tcp: | case MqttConnectionType.Tcp: | ||||
case MqttConnectionType.Tls: | case MqttConnectionType.Tls: | ||||
return new MqttTcpChannel(); | |||||
return new BufferedCommunicationChannel( new MqttTcpChannel() ); | |||||
case MqttConnectionType.Ws: | case MqttConnectionType.Ws: | ||||
case MqttConnectionType.Wss: | case MqttConnectionType.Wss: | ||||
return new MqttWebSocketChannel(); | return new MqttWebSocketChannel(); | ||||
@@ -92,17 +92,15 @@ namespace MQTTnet.Implementations | |||||
} | } | ||||
} | } | ||||
public async Task ReadAsync(byte[] buffer) | |||||
public async Task<ArraySegment<byte>> ReadAsync(int length, byte[] buffer) | |||||
{ | { | ||||
if (buffer == null) throw new ArgumentNullException(nameof(buffer)); | |||||
try | try | ||||
{ | { | ||||
var totalBytes = 0; | var totalBytes = 0; | ||||
do | do | ||||
{ | { | ||||
var read = await _dataStream.ReadAsync(buffer, totalBytes, buffer.Length - totalBytes).ConfigureAwait(false); | |||||
var read = await _dataStream.ReadAsync(buffer, totalBytes, length - totalBytes).ConfigureAwait(false); | |||||
if (read == 0) | if (read == 0) | ||||
{ | { | ||||
throw new MqttCommunicationException(new SocketException((int)SocketError.Disconnecting)); | throw new MqttCommunicationException(new SocketException((int)SocketError.Disconnecting)); | ||||
@@ -110,7 +108,8 @@ namespace MQTTnet.Implementations | |||||
totalBytes += read; | totalBytes += read; | ||||
} | } | ||||
while (totalBytes < buffer.Length); | |||||
while (totalBytes < length); | |||||
return new ArraySegment<byte>(buffer, 0, length); | |||||
} | } | ||||
catch (SocketException exception) | catch (SocketException exception) | ||||
{ | { | ||||
@@ -142,5 +141,10 @@ namespace MQTTnet.Implementations | |||||
return certificates; | return certificates; | ||||
} | } | ||||
public int Peek() | |||||
{ | |||||
return _socket.Available; | |||||
} | |||||
} | } | ||||
} | } |
@@ -11,9 +11,6 @@ namespace MQTTnet.Implementations | |||||
public sealed class MqttWebSocketChannel : IMqttCommunicationChannel, IDisposable | public sealed class MqttWebSocketChannel : IMqttCommunicationChannel, IDisposable | ||||
{ | { | ||||
private ClientWebSocket _webSocket = new ClientWebSocket(); | private ClientWebSocket _webSocket = new ClientWebSocket(); | ||||
private const int BufferSize = 4096; | |||||
private const int BufferAmplifier = 20; | |||||
private readonly byte[] WebSocketBuffer = new byte[BufferSize * BufferAmplifier]; | |||||
private int WebSocketBufferSize; | private int WebSocketBufferSize; | ||||
private int WebSocketBufferOffset; | private int WebSocketBufferOffset; | ||||
@@ -42,50 +39,39 @@ namespace MQTTnet.Implementations | |||||
_webSocket?.Dispose(); | _webSocket?.Dispose(); | ||||
} | } | ||||
public Task ReadAsync(byte[] buffer) | |||||
public async Task<ArraySegment<byte>> ReadAsync(int length, byte[] buffer) | |||||
{ | { | ||||
return Task.WhenAll(ReadToBufferAsync(buffer)); | |||||
await ReadToBufferAsync(length, buffer).ConfigureAwait(false); | |||||
var result = new ArraySegment<byte>(buffer, WebSocketBufferOffset, length); | |||||
WebSocketBufferSize -= length; | |||||
WebSocketBufferOffset += length; | |||||
return result; | |||||
} | } | ||||
private async Task ReadToBufferAsync(byte[] buffer) | |||||
private async Task ReadToBufferAsync(int length, byte[] buffer) | |||||
{ | { | ||||
var temporaryBuffer = new byte[BufferSize]; | |||||
var offset = 0; | |||||
if (WebSocketBufferSize > 0) | |||||
{ | |||||
return; | |||||
} | |||||
while (_webSocket.State == WebSocketState.Open) | |||||
var offset = 0; | |||||
while (_webSocket.State == WebSocketState.Open && WebSocketBufferSize < length) | |||||
{ | { | ||||
if (WebSocketBufferSize == 0) | |||||
WebSocketReceiveResult response; | |||||
do | |||||
{ | { | ||||
WebSocketBufferOffset = 0; | |||||
WebSocketReceiveResult response; | |||||
do | |||||
{ | |||||
response = await _webSocket.ReceiveAsync(new ArraySegment<byte>(temporaryBuffer), CancellationToken.None).ConfigureAwait(false); | |||||
response = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer, offset, buffer.Length - offset), CancellationToken.None).ConfigureAwait(false); | |||||
offset += response.Count; | |||||
} while (!response.EndOfMessage); | |||||
temporaryBuffer.CopyTo(WebSocketBuffer, offset); | |||||
offset += response.Count; | |||||
temporaryBuffer = new byte[BufferSize]; | |||||
} while (!response.EndOfMessage); | |||||
WebSocketBufferSize = response.Count; | |||||
if (response.MessageType == WebSocketMessageType.Close) | |||||
{ | |||||
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).ConfigureAwait(false); | |||||
} | |||||
Buffer.BlockCopy(WebSocketBuffer, 0, buffer, 0, buffer.Length); | |||||
WebSocketBufferSize -= buffer.Length; | |||||
WebSocketBufferOffset += buffer.Length; | |||||
} | |||||
else | |||||
WebSocketBufferSize = response.Count; | |||||
if (response.MessageType == WebSocketMessageType.Close) | |||||
{ | { | ||||
Buffer.BlockCopy(WebSocketBuffer, WebSocketBufferOffset, buffer, 0, buffer.Length); | |||||
WebSocketBufferSize -= buffer.Length; | |||||
WebSocketBufferOffset += buffer.Length; | |||||
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).ConfigureAwait(false); | |||||
} | } | ||||
return; | |||||
} | } | ||||
} | } | ||||
@@ -105,5 +91,10 @@ namespace MQTTnet.Implementations | |||||
throw new MqttCommunicationException(exception); | throw new MqttCommunicationException(exception); | ||||
} | } | ||||
} | } | ||||
public int Peek() | |||||
{ | |||||
return WebSocketBufferSize; | |||||
} | |||||
} | } | ||||
} | } |
@@ -0,0 +1,7 @@ | |||||
namespace MQTTnet.Core.Channel | |||||
{ | |||||
public static class BufferConstants | |||||
{ | |||||
public const int Size = 4096 * 20; | |||||
} | |||||
} |
@@ -0,0 +1,77 @@ | |||||
using System.Threading.Tasks; | |||||
using MQTTnet.Core.Client; | |||||
using System; | |||||
namespace MQTTnet.Core.Channel | |||||
{ | |||||
public class BufferedCommunicationChannel : IMqttCommunicationChannel | |||||
{ | |||||
private IMqttCommunicationChannel _inner { get; } | |||||
private int _bufferSize = 0; | |||||
private int _bufferOffset = 0; | |||||
public BufferedCommunicationChannel(IMqttCommunicationChannel inner) | |||||
{ | |||||
_inner = inner; | |||||
} | |||||
public Task ConnectAsync(MqttClientOptions options) | |||||
{ | |||||
return _inner.ConnectAsync(options); | |||||
} | |||||
public Task DisconnectAsync() | |||||
{ | |||||
return _inner.DisconnectAsync(); | |||||
} | |||||
public int Peek() | |||||
{ | |||||
return _inner.Peek(); | |||||
} | |||||
public async Task<ArraySegment<byte>> ReadAsync(int length, byte[] buffer) | |||||
{ | |||||
//read from buffer | |||||
if (_bufferSize > 0) | |||||
{ | |||||
return ReadFomBuffer(length, buffer); | |||||
} | |||||
var available = _inner.Peek(); | |||||
// if there are less or equal bytes available then requested then just read em | |||||
if (available <= length) | |||||
{ | |||||
return await _inner.ReadAsync(length, buffer); | |||||
} | |||||
//if more bytes are available than requested do buffer them to reduce calls to network buffers | |||||
await WriteToBuffer(available, buffer).ConfigureAwait(false); | |||||
return ReadFomBuffer(length, buffer); | |||||
} | |||||
private async Task WriteToBuffer(int available, byte[] buffer) | |||||
{ | |||||
await _inner.ReadAsync(available, buffer).ConfigureAwait(false); | |||||
_bufferSize = available; | |||||
_bufferOffset = 0; | |||||
} | |||||
private ArraySegment<byte> ReadFomBuffer(int length, byte[] buffer) | |||||
{ | |||||
var result = new ArraySegment<byte>(buffer, _bufferOffset, length); | |||||
_bufferSize -= length; | |||||
_bufferOffset += length; | |||||
if (_bufferSize < 0) | |||||
{ | |||||
} | |||||
return result; | |||||
} | |||||
public Task WriteAsync(byte[] buffer) | |||||
{ | |||||
return _inner.WriteAsync(buffer); | |||||
} | |||||
} | |||||
} |
@@ -1,5 +1,6 @@ | |||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
using MQTTnet.Core.Client; | using MQTTnet.Core.Client; | ||||
using System; | |||||
namespace MQTTnet.Core.Channel | namespace MQTTnet.Core.Channel | ||||
{ | { | ||||
@@ -11,6 +12,11 @@ namespace MQTTnet.Core.Channel | |||||
Task WriteAsync(byte[] buffer); | Task WriteAsync(byte[] buffer); | ||||
Task ReadAsync(byte[] buffer); | |||||
/// <summary> | |||||
/// get the currently available number of bytes without reading them | |||||
/// </summary> | |||||
int Peek(); | |||||
Task<ArraySegment<byte>> ReadAsync(int length, byte[] buffer); | |||||
} | } | ||||
} | } |
@@ -49,13 +49,13 @@ namespace MQTTnet.Core.Serializer | |||||
return ReadBytes(_header.BodyLength - (int)BaseStream.Position); | return ReadBytes(_header.BodyLength - (int)BaseStream.Position); | ||||
} | } | ||||
public static async Task<MqttPacketHeader> ReadHeaderFromSourceAsync(IMqttCommunicationChannel source) | |||||
public static async Task<MqttPacketHeader> ReadHeaderFromSourceAsync(IMqttCommunicationChannel source, byte[] buffer) | |||||
{ | { | ||||
var fixedHeader = await ReadStreamByteAsync(source).ConfigureAwait(false); | |||||
var fixedHeader = await ReadStreamByteAsync(source, buffer).ConfigureAwait(false); | |||||
var byteReader = new ByteReader(fixedHeader); | var byteReader = new ByteReader(fixedHeader); | ||||
byteReader.Read(4); | byteReader.Read(4); | ||||
var controlPacketType = (MqttControlPacketType)byteReader.Read(4); | var controlPacketType = (MqttControlPacketType)byteReader.Read(4); | ||||
var bodyLength = await ReadBodyLengthFromSourceAsync(source).ConfigureAwait(false); | |||||
var bodyLength = await ReadBodyLengthFromSourceAsync(source, buffer).ConfigureAwait(false); | |||||
return new MqttPacketHeader() | return new MqttPacketHeader() | ||||
{ | { | ||||
@@ -65,18 +65,17 @@ namespace MQTTnet.Core.Serializer | |||||
}; | }; | ||||
} | } | ||||
private static async Task<byte> ReadStreamByteAsync(IMqttCommunicationChannel source) | |||||
private static async Task<byte> ReadStreamByteAsync(IMqttCommunicationChannel source, byte[] readBuffer) | |||||
{ | { | ||||
var buffer = new byte[1]; | |||||
await ReadFromSourceAsync(source, buffer).ConfigureAwait(false); | |||||
return buffer[0]; | |||||
var result = await ReadFromSourceAsync(source, 1, readBuffer).ConfigureAwait(false); | |||||
return result.Array[result.Offset]; | |||||
} | } | ||||
public static async Task ReadFromSourceAsync(IMqttCommunicationChannel source, byte[] buffer) | |||||
public static async Task<ArraySegment<byte>> ReadFromSourceAsync(IMqttCommunicationChannel source, int length, byte[] buffer) | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
await source.ReadAsync(buffer); | |||||
return await source.ReadAsync(length, buffer); | |||||
} | } | ||||
catch (Exception exception) | catch (Exception exception) | ||||
{ | { | ||||
@@ -84,7 +83,7 @@ namespace MQTTnet.Core.Serializer | |||||
} | } | ||||
} | } | ||||
private static async Task<int> ReadBodyLengthFromSourceAsync(IMqttCommunicationChannel source) | |||||
private static async Task<int> ReadBodyLengthFromSourceAsync(IMqttCommunicationChannel source, byte[] buffer) | |||||
{ | { | ||||
// Alorithm taken from http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html. | // Alorithm taken from http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html. | ||||
var multiplier = 1; | var multiplier = 1; | ||||
@@ -92,7 +91,7 @@ namespace MQTTnet.Core.Serializer | |||||
byte encodedByte; | byte encodedByte; | ||||
do | do | ||||
{ | { | ||||
encodedByte = await ReadStreamByteAsync(source).ConfigureAwait(false); | |||||
encodedByte = await ReadStreamByteAsync(source, buffer).ConfigureAwait(false); | |||||
value += (encodedByte & 127) * multiplier; | value += (encodedByte & 127) * multiplier; | ||||
multiplier *= 128; | multiplier *= 128; | ||||
if (multiplier > 128 * 128 * 128) | if (multiplier > 128 * 128 * 128) | ||||
@@ -17,6 +17,7 @@ namespace MQTTnet.Core.Serializer | |||||
private static byte[] ProtocolVersionV310Name { get; } = Encoding.UTF8.GetBytes("MQIs"); | private static byte[] ProtocolVersionV310Name { get; } = Encoding.UTF8.GetBytes("MQIs"); | ||||
public MqttProtocolVersion ProtocolVersion { get; set; } = MqttProtocolVersion.V311; | public MqttProtocolVersion ProtocolVersion { get; set; } = MqttProtocolVersion.V311; | ||||
private byte[] _readBuffer = new byte[BufferConstants.Size]; | |||||
public async Task SerializeAsync(MqttBasePacket packet, IMqttCommunicationChannel destination) | public async Task SerializeAsync(MqttBasePacket packet, IMqttCommunicationChannel destination) | ||||
{ | { | ||||
@@ -115,17 +116,13 @@ namespace MQTTnet.Core.Serializer | |||||
public async Task<MqttBasePacket> DeserializeAsync(IMqttCommunicationChannel source) | public async Task<MqttBasePacket> DeserializeAsync(IMqttCommunicationChannel source) | ||||
{ | { | ||||
if (source == null) throw new ArgumentNullException(nameof(source)); | if (source == null) throw new ArgumentNullException(nameof(source)); | ||||
var header = await MqttPacketReader.ReadHeaderFromSourceAsync(source).ConfigureAwait(false); | |||||
var body = new byte[header.BodyLength]; | |||||
if (header.BodyLength > 0) | |||||
{ | |||||
await MqttPacketReader.ReadFromSourceAsync(source, body).ConfigureAwait(false); | |||||
} | |||||
var header = await MqttPacketReader.ReadHeaderFromSourceAsync(source, _readBuffer).ConfigureAwait(false); | |||||
using (var mqttPacketReader = new MqttPacketReader(new MemoryStream(body), header)) | |||||
{ | |||||
var body = await GetBody(source, header).ConfigureAwait(false); | |||||
using (var mqttPacketReader = new MqttPacketReader(body, header)) | |||||
{ | |||||
switch (header.ControlPacketType) | switch (header.ControlPacketType) | ||||
{ | { | ||||
case MqttControlPacketType.Connect: | case MqttControlPacketType.Connect: | ||||
@@ -221,6 +218,17 @@ namespace MQTTnet.Core.Serializer | |||||
} | } | ||||
} | } | ||||
private async Task<MemoryStream> GetBody(IMqttCommunicationChannel source, MqttPacketHeader header) | |||||
{ | |||||
if (header.BodyLength > 0) | |||||
{ | |||||
var segment = await MqttPacketReader.ReadFromSourceAsync(source, header.BodyLength, _readBuffer).ConfigureAwait(false); | |||||
return new MemoryStream(segment.Array, segment.Offset, segment.Count); | |||||
} | |||||
return new MemoryStream(); | |||||
} | |||||
private static MqttBasePacket DeserializeUnsubscribe(MqttPacketReader reader) | private static MqttBasePacket DeserializeUnsubscribe(MqttPacketReader reader) | ||||
{ | { | ||||
var packet = new MqttUnsubscribePacket | var packet = new MqttUnsubscribePacket | ||||
@@ -418,15 +418,21 @@ namespace MQTTnet.Core.Tests | |||||
return _stream.WriteAsync(buffer, 0, buffer.Length); | return _stream.WriteAsync(buffer, 0, buffer.Length); | ||||
} | } | ||||
public Task ReadAsync(byte[] buffer) | |||||
public async Task<ArraySegment<byte>> ReadAsync(int length, byte[] buffer) | |||||
{ | { | ||||
return _stream.ReadAsync(buffer, 0, buffer.Length); | |||||
await _stream.ReadAsync(buffer, 0, length); | |||||
return new ArraySegment<byte>(buffer, 0, length); | |||||
} | } | ||||
public byte[] ToArray() | public byte[] ToArray() | ||||
{ | { | ||||
return _stream.ToArray(); | return _stream.ToArray(); | ||||
} | } | ||||
public int Peek() | |||||
{ | |||||
return (int)_stream.Length - (int)_stream.Position; | |||||
} | |||||
} | } | ||||
private static void SerializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311) | private static void SerializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311) | ||||
@@ -29,7 +29,8 @@ namespace MQTTnet.TestApp.NetFramework | |||||
{ | { | ||||
Server = "localhost", | Server = "localhost", | ||||
ClientId = "XYZ", | ClientId = "XYZ", | ||||
CleanSession = true | |||||
CleanSession = true, | |||||
DefaultCommunicationTimeout = TimeSpan.FromMinutes(10) | |||||
}; | }; | ||||
var client = new MqttClientFactory().CreateMqttClient(options); | var client = new MqttClientFactory().CreateMqttClient(options); | ||||
@@ -128,7 +129,8 @@ namespace MQTTnet.TestApp.NetFramework | |||||
} | } | ||||
return MqttConnectReturnCode.ConnectionAccepted; | return MqttConnectReturnCode.ConnectionAccepted; | ||||
} | |||||
}, | |||||
DefaultCommunicationTimeout = TimeSpan.FromMinutes(10) | |||||
}; | }; | ||||
var mqttServer = new MqttServerFactory().CreateMqttServer(options); | var mqttServer = new MqttServerFactory().CreateMqttServer(options); | ||||
@@ -20,18 +20,18 @@ namespace MQTTnet.TestApp.NetFramework | |||||
Console.WriteLine("1 = Start client"); | Console.WriteLine("1 = Start client"); | ||||
Console.WriteLine("2 = Start server"); | Console.WriteLine("2 = Start server"); | ||||
Console.WriteLine("3 = Start performance test"); | Console.WriteLine("3 = Start performance test"); | ||||
var pressedKey = Console.ReadKey(true); | |||||
if (pressedKey.Key == ConsoleKey.D1) | |||||
{ | |||||
Task.Run(() => RunClientAsync(args)); | |||||
Thread.Sleep(Timeout.Infinite); | |||||
} | |||||
else if (pressedKey.Key == ConsoleKey.D2) | |||||
{ | |||||
Task.Run(() => RunServerAsync(args)); | |||||
Thread.Sleep(Timeout.Infinite); | |||||
} | |||||
else if (pressedKey.Key == ConsoleKey.D3) | |||||
//var pressedKey = Console.ReadKey(true); | |||||
//if (pressedKey.Key == ConsoleKey.D1) | |||||
//{ | |||||
// Task.Run(() => RunClientAsync(args)); | |||||
// Thread.Sleep(Timeout.Infinite); | |||||
//} | |||||
//else if (pressedKey.Key == ConsoleKey.D2) | |||||
//{ | |||||
// Task.Run(() => RunServerAsync(args)); | |||||
// Thread.Sleep(Timeout.Infinite); | |||||
//} | |||||
//else if (pressedKey.Key == ConsoleKey.D3) | |||||
{ | { | ||||
Task.Run(() => PerformanceTest.RunAsync()); | Task.Run(() => PerformanceTest.RunAsync()); | ||||
Thread.Sleep(Timeout.Infinite); | Thread.Sleep(Timeout.Infinite); | ||||