mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-26 16:24:10 +08:00
Merge branch 'develop' into Fix_Bug33
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
<package >
|
<package >
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MQTTnet</id>
|
<id>MQTTnet</id>
|
||||||
<version>2.2.1</version>
|
<version>2.3.0</version>
|
||||||
<authors>Christian Kratky</authors>
|
<authors>Christian Kratky</authors>
|
||||||
<owners>Christian Kratky</owners>
|
<owners>Christian Kratky</owners>
|
||||||
<licenseUrl>https://github.com/chkr1011/MQTTnet/blob/master/LICENSE</licenseUrl>
|
<licenseUrl>https://github.com/chkr1011/MQTTnet/blob/master/LICENSE</licenseUrl>
|
||||||
@@ -10,7 +10,8 @@
|
|||||||
<iconUrl>https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png</iconUrl>
|
<iconUrl>https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png</iconUrl>
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<description>MQTTnet is a .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker).</description>
|
<description>MQTTnet is a .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker).</description>
|
||||||
<releaseNotes>* [Server] Fixed a bug in connection management (Thanks to rydergillen-compacSort)
|
<releaseNotes>* [Client] Added support for web socket communication channel (thanks to nowakpiotr)
|
||||||
|
* [Core] Performance optimizations (thanks to JanEggers)
|
||||||
</releaseNotes>
|
</releaseNotes>
|
||||||
<copyright>Copyright Christian Kratky 2016-2017</copyright>
|
<copyright>Copyright Christian Kratky 2016-2017</copyright>
|
||||||
<tags>MQTT MQTTClient MQTTServer MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Queue Hardware Arduino</tags>
|
<tags>MQTT MQTTClient MQTTServer MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Queue Hardware Arduino</tags>
|
||||||
|
|||||||
@@ -85,7 +85,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);
|
||||||
var clientAdapter = new MqttChannelCommunicationAdapter(new MqttTcpChannel(clientSocket, null), new MqttPacketSerializer());
|
var clientAdapter = new MqttChannelCommunicationAdapter(new MqttTcpChannel(clientSocket, null), new MqttPacketSerializer());
|
||||||
ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(clientSocket.RemoteEndPoint.ToString(), clientAdapter));
|
ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(clientSocket.RemoteEndPoint.ToString(), clientAdapter));
|
||||||
}
|
}
|
||||||
@@ -105,10 +105,10 @@ namespace MQTTnet.Implementations
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var clientSocket = await Task.Factory.FromAsync(_tlsEndpointSocket.BeginAccept, _tlsEndpointSocket.EndAccept, null).ConfigureAwait(false);
|
var clientSocket = await Task.Factory.FromAsync(_tlsEndpointSocket.BeginAccept, _tlsEndpointSocket.EndAccept, null);
|
||||||
|
|
||||||
var sslStream = new SslStream(new NetworkStream(clientSocket));
|
var sslStream = new SslStream(new NetworkStream(clientSocket));
|
||||||
await sslStream.AuthenticateAsServerAsync(_tlsCertificate, false, SslProtocols.Tls12, false).ConfigureAwait(false);
|
await sslStream.AuthenticateAsServerAsync(_tlsCertificate, false, SslProtocols.Tls12, false);
|
||||||
|
|
||||||
var clientAdapter = new MqttChannelCommunicationAdapter(new MqttTcpChannel(clientSocket, sslStream), new MqttPacketSerializer());
|
var clientAdapter = new MqttChannelCommunicationAdapter(new MqttTcpChannel(clientSocket, sslStream), new MqttPacketSerializer());
|
||||||
ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(clientSocket.RemoteEndPoint.ToString(), clientAdapter));
|
ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(clientSocket.RemoteEndPoint.ToString(), clientAdapter));
|
||||||
|
|||||||
@@ -46,11 +46,12 @@ namespace MQTTnet.Implementations
|
|||||||
_socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
_socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
||||||
}
|
}
|
||||||
|
|
||||||
await Task.Factory.FromAsync(_socket.BeginConnect, _socket.EndConnect, options.Server, options.GetPort(), null).ConfigureAwait(false);
|
await Task.Factory.FromAsync(_socket.BeginConnect, _socket.EndConnect, options.Server, options.GetPort(), null);
|
||||||
|
|
||||||
if (options.TlsOptions.UseTls)
|
if (options.TlsOptions.UseTls)
|
||||||
{
|
{
|
||||||
_sslStream = new SslStream(new NetworkStream(_socket, true));
|
_sslStream = new SslStream(new NetworkStream(_socket, true));
|
||||||
|
|
||||||
_dataStream = _sslStream;
|
_dataStream = _sslStream;
|
||||||
await _sslStream.AuthenticateAsClientAsync(options.Server, LoadCertificates(options), SslProtocols.Tls12, options.TlsOptions.CheckCertificateRevocation).ConfigureAwait(false);
|
await _sslStream.AuthenticateAsClientAsync(options.Server, LoadCertificates(options), SslProtocols.Tls12, options.TlsOptions.CheckCertificateRevocation).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-13
@@ -8,20 +8,15 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace MQTTnet.Implementations
|
namespace MQTTnet.Implementations
|
||||||
{
|
{
|
||||||
public sealed class MqttWebSocketsChannel : IMqttCommunicationChannel, IDisposable
|
public sealed class MqttWebSocketChannel : IMqttCommunicationChannel, IDisposable
|
||||||
{
|
{
|
||||||
private ClientWebSocket _webSocket;
|
private ClientWebSocket _webSocket = new ClientWebSocket();
|
||||||
private const int BufferSize = 4096;
|
private const int BufferSize = 4096;
|
||||||
private const int BufferAmplifier = 20;
|
private const int BufferAmplifier = 20;
|
||||||
private readonly byte[] WebSocketBuffer = new byte[BufferSize * BufferAmplifier];
|
private readonly byte[] WebSocketBuffer = new byte[BufferSize * BufferAmplifier];
|
||||||
private int WebSocketBufferSize;
|
private int WebSocketBufferSize;
|
||||||
private int WebSocketBufferOffset;
|
private int WebSocketBufferOffset;
|
||||||
|
|
||||||
public MqttWebSocketsChannel()
|
|
||||||
{
|
|
||||||
_webSocket = new ClientWebSocket();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ConnectAsync(MqttClientOptions options)
|
public async Task ConnectAsync(MqttClientOptions options)
|
||||||
{
|
{
|
||||||
_webSocket = null;
|
_webSocket = null;
|
||||||
@@ -45,10 +40,7 @@ namespace MQTTnet.Implementations
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (_webSocket != null)
|
_webSocket?.Dispose();
|
||||||
{
|
|
||||||
_webSocket.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task ReadAsync(byte[] buffer)
|
public Task ReadAsync(byte[] buffer)
|
||||||
@@ -70,8 +62,7 @@ namespace MQTTnet.Implementations
|
|||||||
WebSocketReceiveResult response;
|
WebSocketReceiveResult response;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
response =
|
response = await _webSocket.ReceiveAsync(new ArraySegment<byte>(temporaryBuffer), CancellationToken.None);
|
||||||
await _webSocket.ReceiveAsync(new ArraySegment<byte>(temporaryBuffer), CancellationToken.None);
|
|
||||||
|
|
||||||
temporaryBuffer.CopyTo(WebSocketBuffer, offset);
|
temporaryBuffer.CopyTo(WebSocketBuffer, offset);
|
||||||
offset += response.Count;
|
offset += response.Count;
|
||||||
@@ -100,6 +100,7 @@
|
|||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Implementations\MqttWebSocketChannel.cs" />
|
||||||
<Compile Include="MqttClientFactory.cs" />
|
<Compile Include="MqttClientFactory.cs" />
|
||||||
<Compile Include="MqttServerFactory.cs" />
|
<Compile Include="MqttServerFactory.cs" />
|
||||||
<Compile Include="Implementations\MqttServerAdapter.cs" />
|
<Compile Include="Implementations\MqttServerAdapter.cs" />
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using MQTTnet.Core.Adapter;
|
using MQTTnet.Core.Adapter;
|
||||||
|
using MQTTnet.Core.Channel;
|
||||||
using MQTTnet.Core.Client;
|
using MQTTnet.Core.Client;
|
||||||
using MQTTnet.Core.Serializer;
|
using MQTTnet.Core.Serializer;
|
||||||
using MQTTnet.Implementations;
|
using MQTTnet.Implementations;
|
||||||
@@ -12,7 +13,23 @@ namespace MQTTnet
|
|||||||
{
|
{
|
||||||
if (options == null) throw new ArgumentNullException(nameof(options));
|
if (options == null) throw new ArgumentNullException(nameof(options));
|
||||||
|
|
||||||
return new MqttClient(options, new MqttChannelCommunicationAdapter(new MqttTcpChannel(), new MqttPacketSerializer()));
|
return new MqttClient(options, new MqttChannelCommunicationAdapter(GetMqttCommunicationChannel(options), new MqttPacketSerializer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IMqttCommunicationChannel GetMqttCommunicationChannel(MqttClientOptions options)
|
||||||
|
{
|
||||||
|
switch (options.ConnectionType)
|
||||||
|
{
|
||||||
|
case MqttConnectionType.Tcp:
|
||||||
|
case MqttConnectionType.Tls:
|
||||||
|
return new MqttTcpChannel();
|
||||||
|
case MqttConnectionType.Ws:
|
||||||
|
case MqttConnectionType.Wss:
|
||||||
|
return new MqttWebSocketChannel();
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,5 +11,5 @@ using System.Runtime.InteropServices;
|
|||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
[assembly: Guid("a480ef90-0eaa-4d9a-b271-47a9c47f6f7d")]
|
[assembly: Guid("a480ef90-0eaa-4d9a-b271-47a9c47f6f7d")]
|
||||||
[assembly: AssemblyVersion("2.2.1.0")]
|
[assembly: AssemblyVersion("2.3.0.0")]
|
||||||
[assembly: AssemblyFileVersion("2.2.1.0")]
|
[assembly: AssemblyFileVersion("2.3.0.0")]
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
using MQTTnet.Core.Channel;
|
||||||
|
using MQTTnet.Core.Client;
|
||||||
|
using MQTTnet.Core.Exceptions;
|
||||||
|
using System;
|
||||||
|
using System.Net.WebSockets;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MQTTnet.Implementations
|
||||||
|
{
|
||||||
|
public sealed class MqttWebSocketChannel : IMqttCommunicationChannel, IDisposable
|
||||||
|
{
|
||||||
|
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 WebSocketBufferOffset;
|
||||||
|
|
||||||
|
public async Task ConnectAsync(MqttClientOptions options)
|
||||||
|
{
|
||||||
|
_webSocket = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_webSocket = new ClientWebSocket();
|
||||||
|
|
||||||
|
await _webSocket.ConnectAsync(new Uri(options.Server), CancellationToken.None);
|
||||||
|
}
|
||||||
|
catch (WebSocketException exception)
|
||||||
|
{
|
||||||
|
throw new MqttCommunicationException(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DisconnectAsync()
|
||||||
|
{
|
||||||
|
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_webSocket?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ReadAsync(byte[] buffer)
|
||||||
|
{
|
||||||
|
return Task.WhenAll(ReadToBufferAsync(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ReadToBufferAsync(byte[] buffer)
|
||||||
|
{
|
||||||
|
var temporaryBuffer = new byte[BufferSize];
|
||||||
|
var offset = 0;
|
||||||
|
|
||||||
|
while (_webSocket.State == WebSocketState.Open)
|
||||||
|
{
|
||||||
|
if (WebSocketBufferSize == 0)
|
||||||
|
{
|
||||||
|
WebSocketBufferOffset = 0;
|
||||||
|
|
||||||
|
WebSocketReceiveResult response;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
response = await _webSocket.ReceiveAsync(new ArraySegment<byte>(temporaryBuffer), CancellationToken.None);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer.BlockCopy(WebSocketBuffer, 0, buffer, 0, buffer.Length);
|
||||||
|
WebSocketBufferSize -= buffer.Length;
|
||||||
|
WebSocketBufferOffset += buffer.Length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Buffer.BlockCopy(WebSocketBuffer, WebSocketBufferOffset, buffer, 0, buffer.Length);
|
||||||
|
WebSocketBufferSize -= buffer.Length;
|
||||||
|
WebSocketBufferOffset += buffer.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task WriteAsync(byte[] buffer)
|
||||||
|
{
|
||||||
|
if (buffer == null) {
|
||||||
|
throw new ArgumentNullException(nameof(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Binary, true,
|
||||||
|
CancellationToken.None);
|
||||||
|
}
|
||||||
|
catch (WebSocketException exception)
|
||||||
|
{
|
||||||
|
throw new MqttCommunicationException(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
<TargetFramework>netstandard1.3</TargetFramework>
|
<TargetFramework>netstandard1.3</TargetFramework>
|
||||||
<AssemblyName>MQTTnet</AssemblyName>
|
<AssemblyName>MQTTnet</AssemblyName>
|
||||||
<RootNamespace>MQTTnet</RootNamespace>
|
<RootNamespace>MQTTnet</RootNamespace>
|
||||||
<AssemblyVersion>2.2.1.0</AssemblyVersion>
|
<AssemblyVersion>2.3.0.0</AssemblyVersion>
|
||||||
<FileVersion>2.2.1.0</FileVersion>
|
<FileVersion>2.3.0.0</FileVersion>
|
||||||
<Version>0.0.0.0</Version>
|
<Version>0.0.0.0</Version>
|
||||||
<Company />
|
<Company />
|
||||||
<Product />
|
<Product />
|
||||||
|
|||||||
@@ -22,15 +22,15 @@ namespace MQTTnet
|
|||||||
{
|
{
|
||||||
switch (options.ConnectionType)
|
switch (options.ConnectionType)
|
||||||
{
|
{
|
||||||
case ConnectionTypes.TCP:
|
case MqttConnectionType.Tcp:
|
||||||
case ConnectionTypes.TLS:
|
case MqttConnectionType.Tls:
|
||||||
return new MqttTcpChannel();
|
return new MqttTcpChannel();
|
||||||
case ConnectionTypes.WS:
|
case MqttConnectionType.Ws:
|
||||||
case ConnectionTypes.WSS:
|
case MqttConnectionType.Wss:
|
||||||
return new MqttWebSocketsChannel();
|
return new MqttWebSocketChannel();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null;
|
throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
using MQTTnet.Core.Channel;
|
||||||
|
using MQTTnet.Core.Client;
|
||||||
|
using MQTTnet.Core.Exceptions;
|
||||||
|
using System;
|
||||||
|
using System.Net.WebSockets;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MQTTnet.Implementations
|
||||||
|
{
|
||||||
|
public sealed class MqttWebSocketChannel : IMqttCommunicationChannel, IDisposable
|
||||||
|
{
|
||||||
|
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 WebSocketBufferOffset;
|
||||||
|
|
||||||
|
public async Task ConnectAsync(MqttClientOptions options)
|
||||||
|
{
|
||||||
|
_webSocket = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_webSocket = new ClientWebSocket();
|
||||||
|
|
||||||
|
await _webSocket.ConnectAsync(new Uri(options.Server), CancellationToken.None);
|
||||||
|
}
|
||||||
|
catch (WebSocketException exception)
|
||||||
|
{
|
||||||
|
throw new MqttCommunicationException(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DisconnectAsync()
|
||||||
|
{
|
||||||
|
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_webSocket?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ReadAsync(byte[] buffer)
|
||||||
|
{
|
||||||
|
return Task.WhenAll(ReadToBufferAsync(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ReadToBufferAsync(byte[] buffer)
|
||||||
|
{
|
||||||
|
var temporaryBuffer = new byte[BufferSize];
|
||||||
|
var offset = 0;
|
||||||
|
|
||||||
|
while (_webSocket.State == WebSocketState.Open)
|
||||||
|
{
|
||||||
|
if (WebSocketBufferSize == 0)
|
||||||
|
{
|
||||||
|
WebSocketBufferOffset = 0;
|
||||||
|
|
||||||
|
WebSocketReceiveResult response;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
response = await _webSocket.ReceiveAsync(new ArraySegment<byte>(temporaryBuffer), CancellationToken.None);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer.BlockCopy(WebSocketBuffer, 0, buffer, 0, buffer.Length);
|
||||||
|
WebSocketBufferSize -= buffer.Length;
|
||||||
|
WebSocketBufferOffset += buffer.Length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Buffer.BlockCopy(WebSocketBuffer, WebSocketBufferOffset, buffer, 0, buffer.Length);
|
||||||
|
WebSocketBufferSize -= buffer.Length;
|
||||||
|
WebSocketBufferOffset += buffer.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task WriteAsync(byte[] buffer)
|
||||||
|
{
|
||||||
|
if (buffer == null) {
|
||||||
|
throw new ArgumentNullException(nameof(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Binary, true,
|
||||||
|
CancellationToken.None);
|
||||||
|
}
|
||||||
|
catch (WebSocketException exception)
|
||||||
|
{
|
||||||
|
throw new MqttCommunicationException(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -110,6 +110,7 @@
|
|||||||
<DocumentationFile>bin\x64\Release\MQTTnet.XML</DocumentationFile>
|
<DocumentationFile>bin\x64\Release\MQTTnet.XML</DocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Implementations\MqttWebSocketChannel.cs" />
|
||||||
<Compile Include="MqttClientFactory.cs" />
|
<Compile Include="MqttClientFactory.cs" />
|
||||||
<Compile Include="Implementations\MqttServerAdapter.cs" />
|
<Compile Include="Implementations\MqttServerAdapter.cs" />
|
||||||
<Compile Include="MqttServerFactory.cs" />
|
<Compile Include="MqttServerFactory.cs" />
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using MQTTnet.Core.Adapter;
|
using MQTTnet.Core.Adapter;
|
||||||
|
using MQTTnet.Core.Channel;
|
||||||
using MQTTnet.Core.Client;
|
using MQTTnet.Core.Client;
|
||||||
using MQTTnet.Core.Serializer;
|
using MQTTnet.Core.Serializer;
|
||||||
using MQTTnet.Implementations;
|
using MQTTnet.Implementations;
|
||||||
@@ -12,7 +13,23 @@ namespace MQTTnet
|
|||||||
{
|
{
|
||||||
if (options == null) throw new ArgumentNullException(nameof(options));
|
if (options == null) throw new ArgumentNullException(nameof(options));
|
||||||
|
|
||||||
return new MqttClient(options, new MqttChannelCommunicationAdapter(new MqttTcpChannel(), new MqttPacketSerializer()));
|
return new MqttClient(options, new MqttChannelCommunicationAdapter(GetMqttCommunicationChannel(options), new MqttPacketSerializer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IMqttCommunicationChannel GetMqttCommunicationChannel(MqttClientOptions options)
|
||||||
|
{
|
||||||
|
switch (options.ConnectionType)
|
||||||
|
{
|
||||||
|
case MqttConnectionType.Tcp:
|
||||||
|
case MqttConnectionType.Tls:
|
||||||
|
return new MqttTcpChannel();
|
||||||
|
case MqttConnectionType.Ws:
|
||||||
|
case MqttConnectionType.Wss:
|
||||||
|
return new MqttWebSocketChannel();
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,5 +10,5 @@ using System.Runtime.InteropServices;
|
|||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
[assembly: AssemblyVersion("2.2.1.0")]
|
[assembly: AssemblyVersion("2.3.0.0")]
|
||||||
[assembly: AssemblyFileVersion("2.2.1.0")]
|
[assembly: AssemblyFileVersion("2.3.0.0")]
|
||||||
@@ -21,21 +21,21 @@ namespace MQTTnet.Core.Adapter
|
|||||||
|
|
||||||
public IMqttPacketSerializer PacketSerializer { get; }
|
public IMqttPacketSerializer PacketSerializer { get; }
|
||||||
|
|
||||||
public async Task ConnectAsync(MqttClientOptions options, TimeSpan timeout)
|
public Task ConnectAsync(MqttClientOptions options, TimeSpan timeout)
|
||||||
{
|
{
|
||||||
await ExecuteWithTimeoutAsync(_channel.ConnectAsync(options), timeout).ConfigureAwait(false);
|
return ExecuteWithTimeoutAsync(_channel.ConnectAsync(options), timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DisconnectAsync()
|
public Task DisconnectAsync()
|
||||||
{
|
{
|
||||||
await _channel.DisconnectAsync().ConfigureAwait(false);
|
return _channel.DisconnectAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendPacketAsync(MqttBasePacket packet, TimeSpan timeout)
|
public Task SendPacketAsync(MqttBasePacket packet, TimeSpan timeout)
|
||||||
{
|
{
|
||||||
MqttTrace.Information(nameof(MqttChannelCommunicationAdapter), $"TX >>> {packet} [Timeout={timeout}]");
|
MqttTrace.Information(nameof(MqttChannelCommunicationAdapter), "TX >>> {0} [Timeout={1}]", packet, timeout);
|
||||||
|
|
||||||
await ExecuteWithTimeoutAsync(PacketSerializer.SerializeAsync(packet, _channel), timeout).ConfigureAwait(false);
|
return ExecuteWithTimeoutAsync(PacketSerializer.SerializeAsync(packet, _channel), timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<MqttBasePacket> ReceivePacketAsync(TimeSpan timeout)
|
public async Task<MqttBasePacket> ReceivePacketAsync(TimeSpan timeout)
|
||||||
@@ -43,11 +43,11 @@ namespace MQTTnet.Core.Adapter
|
|||||||
MqttBasePacket packet;
|
MqttBasePacket packet;
|
||||||
if (timeout > TimeSpan.Zero)
|
if (timeout > TimeSpan.Zero)
|
||||||
{
|
{
|
||||||
packet = await ExecuteWithTimeoutAsync(PacketSerializer.DeserializeAsync(_channel), timeout).ConfigureAwait(false);
|
packet = await ExecuteWithTimeoutAsync(PacketSerializer.DeserializeAsync(_channel), timeout);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
packet = await PacketSerializer.DeserializeAsync(_channel).ConfigureAwait(false);
|
packet = await PacketSerializer.DeserializeAsync(_channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet == null)
|
if (packet == null)
|
||||||
@@ -55,14 +55,14 @@ namespace MQTTnet.Core.Adapter
|
|||||||
throw new MqttProtocolViolationException("Received malformed packet.");
|
throw new MqttProtocolViolationException("Received malformed packet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
MqttTrace.Information(nameof(MqttChannelCommunicationAdapter), $"RX <<< {packet}");
|
MqttTrace.Information(nameof(MqttChannelCommunicationAdapter), "RX <<< {0}", packet);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<TResult> ExecuteWithTimeoutAsync<TResult>(Task<TResult> task, TimeSpan timeout)
|
private static async Task<TResult> ExecuteWithTimeoutAsync<TResult>(Task<TResult> task, TimeSpan timeout)
|
||||||
{
|
{
|
||||||
var timeoutTask = Task.Delay(timeout);
|
var timeoutTask = Task.Delay(timeout);
|
||||||
if (await Task.WhenAny(timeoutTask, task).ConfigureAwait(false) == timeoutTask)
|
if (await Task.WhenAny(timeoutTask, task) == timeoutTask)
|
||||||
{
|
{
|
||||||
throw new MqttCommunicationTimedOutException();
|
throw new MqttCommunicationTimedOutException();
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,7 @@ namespace MQTTnet.Core.Adapter
|
|||||||
private static async Task ExecuteWithTimeoutAsync(Task task, TimeSpan timeout)
|
private static async Task ExecuteWithTimeoutAsync(Task task, TimeSpan timeout)
|
||||||
{
|
{
|
||||||
var timeoutTask = Task.Delay(timeout);
|
var timeoutTask = Task.Delay(timeout);
|
||||||
if (await Task.WhenAny(timeoutTask, task).ConfigureAwait(false) == timeoutTask)
|
if (await Task.WhenAny(timeoutTask, task) == timeoutTask)
|
||||||
{
|
{
|
||||||
throw new MqttCommunicationTimedOutException();
|
throw new MqttCommunicationTimedOutException();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MQTTnet.Core.Client
|
|
||||||
{
|
|
||||||
public enum ConnectionTypes
|
|
||||||
{
|
|
||||||
TCP,
|
|
||||||
TLS,
|
|
||||||
WS,
|
|
||||||
WSS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -53,7 +53,7 @@ namespace MQTTnet.Core.Client
|
|||||||
{
|
{
|
||||||
_disconnectedEventSuspended = false;
|
_disconnectedEventSuspended = false;
|
||||||
|
|
||||||
await _adapter.ConnectAsync(_options, _options.DefaultCommunicationTimeout).ConfigureAwait(false);
|
await _adapter.ConnectAsync(_options, _options.DefaultCommunicationTimeout);
|
||||||
|
|
||||||
MqttTrace.Verbose(nameof(MqttClient), "Connection with server established.");
|
MqttTrace.Verbose(nameof(MqttClient), "Connection with server established.");
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ namespace MQTTnet.Core.Client
|
|||||||
|
|
||||||
StartReceivePackets();
|
StartReceivePackets();
|
||||||
|
|
||||||
var response = await SendAndReceiveAsync<MqttConnAckPacket>(connectPacket).ConfigureAwait(false);
|
var response = await SendAndReceiveAsync<MqttConnAckPacket>(connectPacket);
|
||||||
if (response.ConnectReturnCode != MqttConnectReturnCode.ConnectionAccepted)
|
if (response.ConnectReturnCode != MqttConnectReturnCode.ConnectionAccepted)
|
||||||
{
|
{
|
||||||
await DisconnectInternalAsync().ConfigureAwait(false);
|
await DisconnectInternalAsync();
|
||||||
throw new MqttConnectingFailedException(response.ConnectReturnCode);
|
throw new MqttConnectingFailedException(response.ConnectReturnCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ namespace MQTTnet.Core.Client
|
|||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
await DisconnectInternalAsync().ConfigureAwait(false);
|
await DisconnectInternalAsync();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,11 +101,11 @@ namespace MQTTnet.Core.Client
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await SendAsync(new MqttDisconnectPacket()).ConfigureAwait(false);
|
await SendAsync(new MqttDisconnectPacket());
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
await DisconnectInternalAsync().ConfigureAwait(false);
|
await DisconnectInternalAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ namespace MQTTnet.Core.Client
|
|||||||
return Unsubscribe(topicFilters.ToList());
|
return Unsubscribe(topicFilters.ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Unsubscribe(IList<string> topicFilters)
|
public Task Unsubscribe(IList<string> topicFilters)
|
||||||
{
|
{
|
||||||
if (topicFilters == null) throw new ArgumentNullException(nameof(topicFilters));
|
if (topicFilters == null) throw new ArgumentNullException(nameof(topicFilters));
|
||||||
if (!topicFilters.Any()) throw new MqttProtocolViolationException("At least one topic filter must be set [MQTT-3.10.3-2].");
|
if (!topicFilters.Any()) throw new MqttProtocolViolationException("At least one topic filter must be set [MQTT-3.10.3-2].");
|
||||||
@@ -158,10 +158,10 @@ namespace MQTTnet.Core.Client
|
|||||||
TopicFilters = topicFilters
|
TopicFilters = topicFilters
|
||||||
};
|
};
|
||||||
|
|
||||||
await SendAndReceiveAsync<MqttUnsubAckPacket>(unsubscribePacket).ConfigureAwait(false);
|
return SendAndReceiveAsync<MqttUnsubAckPacket>(unsubscribePacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PublishAsync(MqttApplicationMessage applicationMessage)
|
public Task PublishAsync(MqttApplicationMessage applicationMessage)
|
||||||
{
|
{
|
||||||
if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));
|
if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));
|
||||||
ThrowIfNotConnected();
|
ThrowIfNotConnected();
|
||||||
@@ -171,19 +171,28 @@ namespace MQTTnet.Core.Client
|
|||||||
if (publishPacket.QualityOfServiceLevel == MqttQualityOfServiceLevel.AtMostOnce)
|
if (publishPacket.QualityOfServiceLevel == MqttQualityOfServiceLevel.AtMostOnce)
|
||||||
{
|
{
|
||||||
// No packet identifier is used for QoS 0 [3.3.2.2 Packet Identifier]
|
// No packet identifier is used for QoS 0 [3.3.2.2 Packet Identifier]
|
||||||
await SendAsync(publishPacket).ConfigureAwait(false);
|
return SendAsync(publishPacket);
|
||||||
}
|
}
|
||||||
else if (publishPacket.QualityOfServiceLevel == MqttQualityOfServiceLevel.AtLeastOnce)
|
|
||||||
|
if (publishPacket.QualityOfServiceLevel == MqttQualityOfServiceLevel.AtLeastOnce)
|
||||||
{
|
{
|
||||||
publishPacket.PacketIdentifier = GetNewPacketIdentifier();
|
publishPacket.PacketIdentifier = GetNewPacketIdentifier();
|
||||||
await SendAndReceiveAsync<MqttPubAckPacket>(publishPacket).ConfigureAwait(false);
|
return SendAndReceiveAsync<MqttPubAckPacket>(publishPacket);
|
||||||
}
|
}
|
||||||
else if (publishPacket.QualityOfServiceLevel == MqttQualityOfServiceLevel.ExactlyOnce)
|
|
||||||
|
if (publishPacket.QualityOfServiceLevel == MqttQualityOfServiceLevel.ExactlyOnce)
|
||||||
{
|
{
|
||||||
publishPacket.PacketIdentifier = GetNewPacketIdentifier();
|
publishPacket.PacketIdentifier = GetNewPacketIdentifier();
|
||||||
var pubRecPacket = await SendAndReceiveAsync<MqttPubRecPacket>(publishPacket).ConfigureAwait(false);
|
return PublishExactlyOncePacketAsync(publishPacket);
|
||||||
await SendAndReceiveAsync<MqttPubCompPacket>(pubRecPacket.CreateResponse<MqttPubRelPacket>()).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task PublishExactlyOncePacketAsync(MqttBasePacket publishPacket)
|
||||||
|
{
|
||||||
|
var pubRecPacket = await SendAndReceiveAsync<MqttPubRecPacket>(publishPacket);
|
||||||
|
await SendAndReceiveAsync<MqttPubCompPacket>(pubRecPacket.CreateResponse<MqttPubRelPacket>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThrowIfNotConnected()
|
private void ThrowIfNotConnected()
|
||||||
@@ -195,7 +204,7 @@ namespace MQTTnet.Core.Client
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _adapter.DisconnectAsync().ConfigureAwait(false);
|
await _adapter.DisconnectAsync();
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
@@ -294,14 +303,14 @@ namespace MQTTnet.Core.Client
|
|||||||
throw new MqttCommunicationException("Received a not supported QoS level.");
|
throw new MqttCommunicationException("Received a not supported QoS level.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ProcessReceivedPubRelPacket(MqttPubRelPacket pubRelPacket)
|
private Task ProcessReceivedPubRelPacket(MqttPubRelPacket pubRelPacket)
|
||||||
{
|
{
|
||||||
lock (_unacknowledgedPublishPackets)
|
lock (_unacknowledgedPublishPackets)
|
||||||
{
|
{
|
||||||
_unacknowledgedPublishPackets.Remove(pubRelPacket.PacketIdentifier);
|
_unacknowledgedPublishPackets.Remove(pubRelPacket.PacketIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
await SendAsync(pubRelPacket.CreateResponse<MqttPubCompPacket>()).ConfigureAwait(false);
|
return SendAsync(pubRelPacket.CreateResponse<MqttPubCompPacket>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task SendAsync(MqttBasePacket packet)
|
private Task SendAsync(MqttBasePacket packet)
|
||||||
@@ -326,8 +335,8 @@ namespace MQTTnet.Core.Client
|
|||||||
return pi1.PacketIdentifier == pi2.PacketIdentifier;
|
return pi1.PacketIdentifier == pi2.PacketIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
await _adapter.SendPacketAsync(requestPacket, _options.DefaultCommunicationTimeout).ConfigureAwait(false);
|
await _adapter.SendPacketAsync(requestPacket, _options.DefaultCommunicationTimeout);
|
||||||
return (TResponsePacket)await _packetDispatcher.WaitForPacketAsync(ResponsePacketSelector, _options.DefaultCommunicationTimeout).ConfigureAwait(false);
|
return (TResponsePacket)await _packetDispatcher.WaitForPacketAsync(ResponsePacketSelector, _options.DefaultCommunicationTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ushort GetNewPacketIdentifier()
|
private ushort GetNewPacketIdentifier()
|
||||||
@@ -343,19 +352,19 @@ namespace MQTTnet.Core.Client
|
|||||||
{
|
{
|
||||||
while (!cancellationToken.IsCancellationRequested)
|
while (!cancellationToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
await Task.Delay(_options.KeepAlivePeriod, cancellationToken).ConfigureAwait(false);
|
await Task.Delay(_options.KeepAlivePeriod, cancellationToken);
|
||||||
await SendAndReceiveAsync<MqttPingRespPacket>(new MqttPingReqPacket()).ConfigureAwait(false);
|
await SendAndReceiveAsync<MqttPingRespPacket>(new MqttPingReqPacket());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (MqttCommunicationException exception)
|
catch (MqttCommunicationException exception)
|
||||||
{
|
{
|
||||||
MqttTrace.Warning(nameof(MqttClient), exception, "MQTT communication error while receiving packets.");
|
MqttTrace.Warning(nameof(MqttClient), exception, "MQTT communication error while receiving packets.");
|
||||||
await DisconnectInternalAsync().ConfigureAwait(false);
|
await DisconnectInternalAsync();
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
MqttTrace.Warning(nameof(MqttClient), exception, "Error while sending/receiving keep alive packets.");
|
MqttTrace.Warning(nameof(MqttClient), exception, "Error while sending/receiving keep alive packets.");
|
||||||
await DisconnectInternalAsync().ConfigureAwait(false);
|
await DisconnectInternalAsync();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -370,8 +379,8 @@ namespace MQTTnet.Core.Client
|
|||||||
{
|
{
|
||||||
while (!cancellationToken.IsCancellationRequested)
|
while (!cancellationToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
var packet = await _adapter.ReceivePacketAsync(TimeSpan.Zero).ConfigureAwait(false);
|
var packet = await _adapter.ReceivePacketAsync(TimeSpan.Zero);
|
||||||
MqttTrace.Information(nameof(MqttClient), $"Received <<< {packet}");
|
MqttTrace.Information(nameof(MqttClient), "Received <<< {0}", packet);
|
||||||
|
|
||||||
StartProcessReceivedPacket(packet, cancellationToken);
|
StartProcessReceivedPacket(packet, cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -379,12 +388,12 @@ namespace MQTTnet.Core.Client
|
|||||||
catch (MqttCommunicationException exception)
|
catch (MqttCommunicationException exception)
|
||||||
{
|
{
|
||||||
MqttTrace.Warning(nameof(MqttClient), exception, "MQTT communication exception while receiving packets.");
|
MqttTrace.Warning(nameof(MqttClient), exception, "MQTT communication exception while receiving packets.");
|
||||||
await DisconnectInternalAsync().ConfigureAwait(false);
|
await DisconnectInternalAsync();
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
MqttTrace.Error(nameof(MqttClient), exception, "Unhandled exception while receiving packets.");
|
MqttTrace.Error(nameof(MqttClient), exception, "Unhandled exception while receiving packets.");
|
||||||
await DisconnectInternalAsync().ConfigureAwait(false);
|
await DisconnectInternalAsync();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,6 +25,6 @@ namespace MQTTnet.Core.Client
|
|||||||
|
|
||||||
public MqttProtocolVersion ProtocolVersion { get; set; } = MqttProtocolVersion.V311;
|
public MqttProtocolVersion ProtocolVersion { get; set; } = MqttProtocolVersion.V311;
|
||||||
|
|
||||||
public ConnectionTypes ConnectionType { get; set; } = ConnectionTypes.TCP;
|
public MqttConnectionType ConnectionType { get; set; } = MqttConnectionType.Tcp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace MQTTnet.Core.Client
|
||||||
|
{
|
||||||
|
public enum MqttConnectionType
|
||||||
|
{
|
||||||
|
Tcp,
|
||||||
|
Tls,
|
||||||
|
Ws,
|
||||||
|
Wss
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace MQTTnet.Core.Diagnostics
|
namespace MQTTnet.Core.Diagnostics
|
||||||
{
|
{
|
||||||
@@ -6,39 +7,58 @@ namespace MQTTnet.Core.Diagnostics
|
|||||||
{
|
{
|
||||||
public static event EventHandler<MqttTraceMessagePublishedEventArgs> TraceMessagePublished;
|
public static event EventHandler<MqttTraceMessagePublishedEventArgs> TraceMessagePublished;
|
||||||
|
|
||||||
public static void Verbose(string source, string message)
|
public static void Verbose(string source, string message, params object[] parameters)
|
||||||
{
|
{
|
||||||
Publish(source, MqttTraceLevel.Verbose, null, message);
|
Publish(source, MqttTraceLevel.Verbose, null, message, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Information(string source, string message)
|
public static void Information(string source, string message, params object[] parameters)
|
||||||
{
|
{
|
||||||
Publish(source, MqttTraceLevel.Information, null, message);
|
Publish(source, MqttTraceLevel.Information, null, message, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Warning(string source, string message)
|
public static void Warning(string source, string message, params object[] parameters)
|
||||||
{
|
{
|
||||||
Publish(source, MqttTraceLevel.Warning, null, message);
|
Publish(source, MqttTraceLevel.Warning, null, message, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Warning(string source, Exception exception, string message)
|
public static void Warning(string source, Exception exception, string message, params object[] parameters)
|
||||||
{
|
{
|
||||||
Publish(source, MqttTraceLevel.Warning, exception, message);
|
Publish(source, MqttTraceLevel.Warning, exception, message, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Error(string source, string message)
|
public static void Error(string source, string message, params object[] parameters)
|
||||||
{
|
{
|
||||||
Publish(source, MqttTraceLevel.Error, null, message);
|
Publish(source, MqttTraceLevel.Error, null, message, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Error(string source, Exception exception, string message)
|
public static void Error(string source, Exception exception, string message, params object[] parameters)
|
||||||
{
|
{
|
||||||
Publish(source, MqttTraceLevel.Error, exception, message);
|
Publish(source, MqttTraceLevel.Error, exception, message, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Publish(string source, MqttTraceLevel traceLevel, Exception exception, string message)
|
private static void Publish(string source, MqttTraceLevel traceLevel, Exception exception, string message, params object[] parameters)
|
||||||
{
|
{
|
||||||
TraceMessagePublished?.Invoke(null, new MqttTraceMessagePublishedEventArgs(Environment.CurrentManagedThreadId, source, traceLevel, message, exception));
|
var handler = TraceMessagePublished;
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parameters?.Length > 0)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
message = string.Format(message, parameters);
|
||||||
|
}
|
||||||
|
catch (Exception formatException)
|
||||||
|
{
|
||||||
|
Error(nameof(MqttTrace), formatException, "Error while tracing message: " + message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.Invoke(null, new MqttTraceMessagePublishedEventArgs(Environment.CurrentManagedThreadId, source, traceLevel, message, exception));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
<PackageIconUrl></PackageIconUrl>
|
<PackageIconUrl></PackageIconUrl>
|
||||||
<RepositoryUrl></RepositoryUrl>
|
<RepositoryUrl></RepositoryUrl>
|
||||||
<PackageTags></PackageTags>
|
<PackageTags></PackageTags>
|
||||||
<FileVersion>2.2.1.0</FileVersion>
|
<FileVersion>2.3.0.0</FileVersion>
|
||||||
<AssemblyVersion>2.2.1.0</AssemblyVersion>
|
<AssemblyVersion>2.3.0.0</AssemblyVersion>
|
||||||
<PackageLicenseUrl></PackageLicenseUrl>
|
<PackageLicenseUrl></PackageLicenseUrl>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace MQTTnet.Core.Serializer
|
|||||||
public async Task ReadToEndAsync()
|
public async Task ReadToEndAsync()
|
||||||
{
|
{
|
||||||
await ReadFixedHeaderAsync();
|
await ReadFixedHeaderAsync();
|
||||||
await ReadRemainingLengthAsync().ConfigureAwait(false);
|
await ReadRemainingLengthAsync();
|
||||||
|
|
||||||
if (_remainingLength == 0)
|
if (_remainingLength == 0)
|
||||||
{
|
{
|
||||||
@@ -37,20 +37,20 @@ namespace MQTTnet.Core.Serializer
|
|||||||
}
|
}
|
||||||
|
|
||||||
var buffer = new byte[_remainingLength];
|
var buffer = new byte[_remainingLength];
|
||||||
await ReadFromSourceAsync(buffer).ConfigureAwait(false);
|
await ReadFromSourceAsync(buffer);
|
||||||
|
|
||||||
_remainingData.Write(buffer, 0, buffer.Length);
|
_remainingData.Write(buffer, 0, buffer.Length);
|
||||||
_remainingData.Position = 0;
|
_remainingData.Position = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<byte> ReadRemainingDataByteAsync()
|
public byte ReadRemainingDataByte()
|
||||||
{
|
{
|
||||||
return (await ReadRemainingDataAsync(1).ConfigureAwait(false))[0];
|
return ReadRemainingData(1)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ushort> ReadRemainingDataUShortAsync()
|
public ushort ReadRemainingDataUShort()
|
||||||
{
|
{
|
||||||
var buffer = await ReadRemainingDataAsync(2).ConfigureAwait(false);
|
var buffer = ReadRemainingData(2);
|
||||||
|
|
||||||
var temp = buffer[0];
|
var temp = buffer[0];
|
||||||
buffer[0] = buffer[1];
|
buffer[0] = buffer[1];
|
||||||
@@ -59,28 +59,27 @@ namespace MQTTnet.Core.Serializer
|
|||||||
return BitConverter.ToUInt16(buffer, 0);
|
return BitConverter.ToUInt16(buffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> ReadRemainingDataStringWithLengthPrefixAsync()
|
public string ReadRemainingDataStringWithLengthPrefix()
|
||||||
{
|
{
|
||||||
var buffer = await ReadRemainingDataWithLengthPrefixAsync();
|
var buffer = ReadRemainingDataWithLengthPrefix();
|
||||||
return Encoding.UTF8.GetString(buffer, 0, buffer.Length);
|
return Encoding.UTF8.GetString(buffer, 0, buffer.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<byte[]> ReadRemainingDataWithLengthPrefixAsync()
|
public byte[] ReadRemainingDataWithLengthPrefix()
|
||||||
{
|
{
|
||||||
var length = await ReadRemainingDataUShortAsync();
|
var length = ReadRemainingDataUShort();
|
||||||
return await ReadRemainingDataAsync(length).ConfigureAwait(false);
|
return ReadRemainingData(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<byte[]> ReadRemainingDataAsync()
|
public byte[] ReadRemainingData()
|
||||||
{
|
{
|
||||||
return ReadRemainingDataAsync(_remainingLength - (int)_remainingData.Position);
|
return ReadRemainingData(_remainingLength - (int)_remainingData.Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<byte[]> ReadRemainingDataAsync(int length)
|
public byte[] ReadRemainingData(int length)
|
||||||
{
|
{
|
||||||
var buffer = new byte[length];
|
var buffer = new byte[length];
|
||||||
await _remainingData.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
|
_remainingData.Read(buffer, 0, buffer.Length);
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +91,7 @@ namespace MQTTnet.Core.Serializer
|
|||||||
byte encodedByte;
|
byte encodedByte;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
encodedByte = await ReadStreamByteAsync().ConfigureAwait(false);
|
encodedByte = await ReadStreamByteAsync();
|
||||||
value += (encodedByte & 127) * multiplier;
|
value += (encodedByte & 127) * multiplier;
|
||||||
multiplier *= 128;
|
multiplier *= 128;
|
||||||
if (multiplier > 128 * 128 * 128)
|
if (multiplier > 128 * 128 * 128)
|
||||||
@@ -119,13 +118,13 @@ namespace MQTTnet.Core.Serializer
|
|||||||
private async Task<byte> ReadStreamByteAsync()
|
private async Task<byte> ReadStreamByteAsync()
|
||||||
{
|
{
|
||||||
var buffer = new byte[1];
|
var buffer = new byte[1];
|
||||||
await ReadFromSourceAsync(buffer).ConfigureAwait(false);
|
await ReadFromSourceAsync(buffer);
|
||||||
return buffer[0];
|
return buffer[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ReadFixedHeaderAsync()
|
private async Task ReadFixedHeaderAsync()
|
||||||
{
|
{
|
||||||
FixedHeader = await ReadStreamByteAsync().ConfigureAwait(false);
|
FixedHeader = await ReadStreamByteAsync();
|
||||||
|
|
||||||
var byteReader = new ByteReader(FixedHeader);
|
var byteReader = new ByteReader(FixedHeader);
|
||||||
byteReader.Read(4);
|
byteReader.Read(4);
|
||||||
|
|||||||
@@ -106,12 +106,12 @@ namespace MQTTnet.Core.Serializer
|
|||||||
{
|
{
|
||||||
case MqttControlPacketType.Connect:
|
case MqttControlPacketType.Connect:
|
||||||
{
|
{
|
||||||
return await DeserializeConnectAsync(mqttPacketReader).ConfigureAwait(false);
|
return DeserializeConnect(mqttPacketReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
case MqttControlPacketType.ConnAck:
|
case MqttControlPacketType.ConnAck:
|
||||||
{
|
{
|
||||||
return await DeserializeConnAck(mqttPacketReader).ConfigureAwait(false);
|
return DeserializeConnAck(mqttPacketReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
case MqttControlPacketType.Disconnect:
|
case MqttControlPacketType.Disconnect:
|
||||||
@@ -121,14 +121,14 @@ namespace MQTTnet.Core.Serializer
|
|||||||
|
|
||||||
case MqttControlPacketType.Publish:
|
case MqttControlPacketType.Publish:
|
||||||
{
|
{
|
||||||
return await DeserializePublishAsync(mqttPacketReader).ConfigureAwait(false);
|
return DeserializePublish(mqttPacketReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
case MqttControlPacketType.PubAck:
|
case MqttControlPacketType.PubAck:
|
||||||
{
|
{
|
||||||
return new MqttPubAckPacket
|
return new MqttPubAckPacket
|
||||||
{
|
{
|
||||||
PacketIdentifier = await mqttPacketReader.ReadRemainingDataUShortAsync().ConfigureAwait(false)
|
PacketIdentifier = mqttPacketReader.ReadRemainingDataUShort()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ namespace MQTTnet.Core.Serializer
|
|||||||
{
|
{
|
||||||
return new MqttPubRecPacket
|
return new MqttPubRecPacket
|
||||||
{
|
{
|
||||||
PacketIdentifier = await mqttPacketReader.ReadRemainingDataUShortAsync().ConfigureAwait(false)
|
PacketIdentifier = mqttPacketReader.ReadRemainingDataUShort()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ namespace MQTTnet.Core.Serializer
|
|||||||
{
|
{
|
||||||
return new MqttPubRelPacket
|
return new MqttPubRelPacket
|
||||||
{
|
{
|
||||||
PacketIdentifier = await mqttPacketReader.ReadRemainingDataUShortAsync().ConfigureAwait(false)
|
PacketIdentifier = mqttPacketReader.ReadRemainingDataUShort()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ namespace MQTTnet.Core.Serializer
|
|||||||
{
|
{
|
||||||
return new MqttPubCompPacket
|
return new MqttPubCompPacket
|
||||||
{
|
{
|
||||||
PacketIdentifier = await mqttPacketReader.ReadRemainingDataUShortAsync().ConfigureAwait(false)
|
PacketIdentifier = mqttPacketReader.ReadRemainingDataUShort()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,24 +168,24 @@ namespace MQTTnet.Core.Serializer
|
|||||||
|
|
||||||
case MqttControlPacketType.Subscribe:
|
case MqttControlPacketType.Subscribe:
|
||||||
{
|
{
|
||||||
return await DeserializeSubscribeAsync(mqttPacketReader).ConfigureAwait(false);
|
return DeserializeSubscribe(mqttPacketReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
case MqttControlPacketType.SubAck:
|
case MqttControlPacketType.SubAck:
|
||||||
{
|
{
|
||||||
return await DeserializeSubAck(mqttPacketReader).ConfigureAwait(false);
|
return DeserializeSubAck(mqttPacketReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
case MqttControlPacketType.Unsubscibe:
|
case MqttControlPacketType.Unsubscibe:
|
||||||
{
|
{
|
||||||
return await DeserializeUnsubscribeAsync(mqttPacketReader).ConfigureAwait(false);
|
return DeserializeUnsubscribe(mqttPacketReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
case MqttControlPacketType.UnsubAck:
|
case MqttControlPacketType.UnsubAck:
|
||||||
{
|
{
|
||||||
return new MqttUnsubAckPacket
|
return new MqttUnsubAckPacket
|
||||||
{
|
{
|
||||||
PacketIdentifier = await mqttPacketReader.ReadRemainingDataUShortAsync().ConfigureAwait(false)
|
PacketIdentifier = mqttPacketReader.ReadRemainingDataUShort()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,51 +197,51 @@ namespace MQTTnet.Core.Serializer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<MqttBasePacket> DeserializeUnsubscribeAsync(MqttPacketReader reader)
|
private static MqttBasePacket DeserializeUnsubscribe(MqttPacketReader reader)
|
||||||
{
|
{
|
||||||
var packet = new MqttUnsubscribePacket
|
var packet = new MqttUnsubscribePacket
|
||||||
{
|
{
|
||||||
PacketIdentifier = await reader.ReadRemainingDataUShortAsync().ConfigureAwait(false),
|
PacketIdentifier = reader.ReadRemainingDataUShort(),
|
||||||
};
|
};
|
||||||
|
|
||||||
while (!reader.EndOfRemainingData)
|
while (!reader.EndOfRemainingData)
|
||||||
{
|
{
|
||||||
packet.TopicFilters.Add(await reader.ReadRemainingDataStringWithLengthPrefixAsync().ConfigureAwait(false));
|
packet.TopicFilters.Add(reader.ReadRemainingDataStringWithLengthPrefix());
|
||||||
}
|
}
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<MqttBasePacket> DeserializeSubscribeAsync(MqttPacketReader reader)
|
private static MqttBasePacket DeserializeSubscribe(MqttPacketReader reader)
|
||||||
{
|
{
|
||||||
var packet = new MqttSubscribePacket
|
var packet = new MqttSubscribePacket
|
||||||
{
|
{
|
||||||
PacketIdentifier = await reader.ReadRemainingDataUShortAsync().ConfigureAwait(false),
|
PacketIdentifier = reader.ReadRemainingDataUShort()
|
||||||
};
|
};
|
||||||
|
|
||||||
while (!reader.EndOfRemainingData)
|
while (!reader.EndOfRemainingData)
|
||||||
{
|
{
|
||||||
packet.TopicFilters.Add(new TopicFilter(
|
packet.TopicFilters.Add(new TopicFilter(
|
||||||
await reader.ReadRemainingDataStringWithLengthPrefixAsync(),
|
reader.ReadRemainingDataStringWithLengthPrefix(),
|
||||||
(MqttQualityOfServiceLevel)await reader.ReadRemainingDataByteAsync().ConfigureAwait(false)));
|
(MqttQualityOfServiceLevel)reader.ReadRemainingDataByte()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<MqttBasePacket> DeserializePublishAsync(MqttPacketReader reader)
|
private static MqttBasePacket DeserializePublish(MqttPacketReader reader)
|
||||||
{
|
{
|
||||||
var fixedHeader = new ByteReader(reader.FixedHeader);
|
var fixedHeader = new ByteReader(reader.FixedHeader);
|
||||||
var retain = fixedHeader.Read();
|
var retain = fixedHeader.Read();
|
||||||
var qualityOfServiceLevel = (MqttQualityOfServiceLevel)fixedHeader.Read(2);
|
var qualityOfServiceLevel = (MqttQualityOfServiceLevel)fixedHeader.Read(2);
|
||||||
var dup = fixedHeader.Read();
|
var dup = fixedHeader.Read();
|
||||||
|
|
||||||
var topic = await reader.ReadRemainingDataStringWithLengthPrefixAsync().ConfigureAwait(false);
|
var topic = reader.ReadRemainingDataStringWithLengthPrefix();
|
||||||
|
|
||||||
ushort packetIdentifier = 0;
|
ushort packetIdentifier = 0;
|
||||||
if (qualityOfServiceLevel > MqttQualityOfServiceLevel.AtMostOnce)
|
if (qualityOfServiceLevel > MqttQualityOfServiceLevel.AtMostOnce)
|
||||||
{
|
{
|
||||||
packetIdentifier = await reader.ReadRemainingDataUShortAsync().ConfigureAwait(false);
|
packetIdentifier = reader.ReadRemainingDataUShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
var packet = new MqttPublishPacket
|
var packet = new MqttPublishPacket
|
||||||
@@ -250,22 +250,22 @@ namespace MQTTnet.Core.Serializer
|
|||||||
QualityOfServiceLevel = qualityOfServiceLevel,
|
QualityOfServiceLevel = qualityOfServiceLevel,
|
||||||
Dup = dup,
|
Dup = dup,
|
||||||
Topic = topic,
|
Topic = topic,
|
||||||
Payload = await reader.ReadRemainingDataAsync().ConfigureAwait(false),
|
Payload = reader.ReadRemainingData(),
|
||||||
PacketIdentifier = packetIdentifier
|
PacketIdentifier = packetIdentifier
|
||||||
};
|
};
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<MqttBasePacket> DeserializeConnectAsync(MqttPacketReader reader)
|
private static MqttBasePacket DeserializeConnect(MqttPacketReader reader)
|
||||||
{
|
{
|
||||||
await reader.ReadRemainingDataAsync(2).ConfigureAwait(false); // Skip 2 bytes
|
reader.ReadRemainingData(2); // Skip 2 bytes
|
||||||
|
|
||||||
MqttProtocolVersion protocolVersion;
|
MqttProtocolVersion protocolVersion;
|
||||||
var protocolName = await reader.ReadRemainingDataAsync(4).ConfigureAwait(false);
|
var protocolName = reader.ReadRemainingData(4);
|
||||||
if (protocolName.SequenceEqual(ProtocolVersionV310Name))
|
if (protocolName.SequenceEqual(ProtocolVersionV310Name))
|
||||||
{
|
{
|
||||||
await reader.ReadRemainingDataAsync(2).ConfigureAwait(false);
|
reader.ReadRemainingData(2);
|
||||||
protocolVersion = MqttProtocolVersion.V310;
|
protocolVersion = MqttProtocolVersion.V310;
|
||||||
}
|
}
|
||||||
else if (protocolName.SequenceEqual(ProtocolVersionV311Name))
|
else if (protocolName.SequenceEqual(ProtocolVersionV311Name))
|
||||||
@@ -277,8 +277,8 @@ namespace MQTTnet.Core.Serializer
|
|||||||
throw new MqttProtocolViolationException("Protocol name is not supported.");
|
throw new MqttProtocolViolationException("Protocol name is not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var protocolLevel = await reader.ReadRemainingDataByteAsync().ConfigureAwait(false);
|
var protocolLevel = reader.ReadRemainingDataByte();
|
||||||
var connectFlags = await reader.ReadRemainingDataByteAsync().ConfigureAwait(false);
|
var connectFlags = reader.ReadRemainingDataByte();
|
||||||
|
|
||||||
var connectFlagsReader = new ByteReader(connectFlags);
|
var connectFlagsReader = new ByteReader(connectFlags);
|
||||||
connectFlagsReader.Read(); // Reserved.
|
connectFlagsReader.Read(); // Reserved.
|
||||||
@@ -295,51 +295,51 @@ namespace MQTTnet.Core.Serializer
|
|||||||
var passwordFlag = connectFlagsReader.Read();
|
var passwordFlag = connectFlagsReader.Read();
|
||||||
var usernameFlag = connectFlagsReader.Read();
|
var usernameFlag = connectFlagsReader.Read();
|
||||||
|
|
||||||
packet.KeepAlivePeriod = await reader.ReadRemainingDataUShortAsync().ConfigureAwait(false);
|
packet.KeepAlivePeriod = reader.ReadRemainingDataUShort();
|
||||||
packet.ClientId = await reader.ReadRemainingDataStringWithLengthPrefixAsync().ConfigureAwait(false);
|
packet.ClientId = reader.ReadRemainingDataStringWithLengthPrefix();
|
||||||
|
|
||||||
if (willFlag)
|
if (willFlag)
|
||||||
{
|
{
|
||||||
packet.WillMessage = new MqttApplicationMessage(
|
packet.WillMessage = new MqttApplicationMessage(
|
||||||
await reader.ReadRemainingDataStringWithLengthPrefixAsync().ConfigureAwait(false),
|
reader.ReadRemainingDataStringWithLengthPrefix(),
|
||||||
await reader.ReadRemainingDataWithLengthPrefixAsync().ConfigureAwait(false),
|
reader.ReadRemainingDataWithLengthPrefix(),
|
||||||
(MqttQualityOfServiceLevel)willQoS,
|
(MqttQualityOfServiceLevel)willQoS,
|
||||||
willRetain);
|
willRetain);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usernameFlag)
|
if (usernameFlag)
|
||||||
{
|
{
|
||||||
packet.Username = await reader.ReadRemainingDataStringWithLengthPrefixAsync().ConfigureAwait(false);
|
packet.Username = reader.ReadRemainingDataStringWithLengthPrefix();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (passwordFlag)
|
if (passwordFlag)
|
||||||
{
|
{
|
||||||
packet.Password = await reader.ReadRemainingDataStringWithLengthPrefixAsync().ConfigureAwait(false);
|
packet.Password = reader.ReadRemainingDataStringWithLengthPrefix();
|
||||||
}
|
}
|
||||||
|
|
||||||
ValidateConnectPacket(packet);
|
ValidateConnectPacket(packet);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<MqttBasePacket> DeserializeSubAck(MqttPacketReader reader)
|
private static MqttBasePacket DeserializeSubAck(MqttPacketReader reader)
|
||||||
{
|
{
|
||||||
var packet = new MqttSubAckPacket
|
var packet = new MqttSubAckPacket
|
||||||
{
|
{
|
||||||
PacketIdentifier = await reader.ReadRemainingDataUShortAsync().ConfigureAwait(false)
|
PacketIdentifier = reader.ReadRemainingDataUShort()
|
||||||
};
|
};
|
||||||
|
|
||||||
while (!reader.EndOfRemainingData)
|
while (!reader.EndOfRemainingData)
|
||||||
{
|
{
|
||||||
packet.SubscribeReturnCodes.Add((MqttSubscribeReturnCode)await reader.ReadRemainingDataByteAsync().ConfigureAwait(false));
|
packet.SubscribeReturnCodes.Add((MqttSubscribeReturnCode)reader.ReadRemainingDataByte());
|
||||||
}
|
}
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<MqttBasePacket> DeserializeConnAck(MqttPacketReader reader)
|
private static MqttBasePacket DeserializeConnAck(MqttPacketReader reader)
|
||||||
{
|
{
|
||||||
var variableHeader1 = await reader.ReadRemainingDataByteAsync().ConfigureAwait(false);
|
var variableHeader1 = reader.ReadRemainingDataByte();
|
||||||
var variableHeader2 = await reader.ReadRemainingDataByteAsync().ConfigureAwait(false);
|
var variableHeader2 = reader.ReadRemainingDataByte();
|
||||||
|
|
||||||
var packet = new MqttConnAckPacket
|
var packet = new MqttConnAckPacket
|
||||||
{
|
{
|
||||||
@@ -457,7 +457,7 @@ namespace MQTTnet.Core.Serializer
|
|||||||
output.Write(packet.PacketIdentifier);
|
output.Write(packet.PacketIdentifier);
|
||||||
|
|
||||||
output.InjectFixedHeader(MqttControlPacketType.PubRel, 0x02);
|
output.InjectFixedHeader(MqttControlPacketType.PubRel, 0x02);
|
||||||
await output.WriteToAsync(destination).ConfigureAwait(false);
|
await output.WriteToAsync(destination);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ namespace MQTTnet.Core.Server
|
|||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
MqttTrace.Error(nameof(MqttClientSession), exception, $"Client '{_identifier}': Unhandled exception while processing client packets.");
|
MqttTrace.Error(nameof(MqttClientSession), exception, "Client '{0}': Unhandled exception while processing client packets.", _identifier);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -90,7 +90,7 @@ namespace MQTTnet.Core.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
_messageQueue.Enqueue(publishPacket);
|
_messageQueue.Enqueue(publishPacket);
|
||||||
MqttTrace.Verbose(nameof(MqttClientSession), $"Client '{_identifier}: Enqueued pending publish packet.");
|
MqttTrace.Verbose(nameof(MqttClientSession), "Client '{0}': Enqueued pending publish packet.", _identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
@@ -143,7 +143,7 @@ namespace MQTTnet.Core.Server
|
|||||||
return Task.FromResult((object)null);
|
return Task.FromResult((object)null);
|
||||||
}
|
}
|
||||||
|
|
||||||
MqttTrace.Warning(nameof(MqttClientSession), $"Client '{_identifier}': Received not supported packet ({packet}). Closing connection.");
|
MqttTrace.Warning(nameof(MqttClientSession), "Client '{0}': Received not supported packet ({1}). Closing connection.", _identifier, packet);
|
||||||
_cancellationTokenSource.Cancel();
|
_cancellationTokenSource.Cancel();
|
||||||
|
|
||||||
return Task.FromResult((object)null);
|
return Task.FromResult((object)null);
|
||||||
|
|||||||
@@ -111,11 +111,11 @@ namespace MQTTnet.Core.Server
|
|||||||
_clientSessions.Remove(connectPacket.ClientId);
|
_clientSessions.Remove(connectPacket.ClientId);
|
||||||
clientSession.Dispose();
|
clientSession.Dispose();
|
||||||
clientSession = null;
|
clientSession = null;
|
||||||
MqttTrace.Verbose(nameof(MqttClientSessionsManager), $"Disposed existing session of client '{connectPacket.ClientId}'.");
|
MqttTrace.Verbose(nameof(MqttClientSessionsManager), "Disposed existing session of client '{0}'.", connectPacket.ClientId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MqttTrace.Verbose(nameof(MqttClientSessionsManager), $"Reusing existing session of client '{connectPacket.ClientId}'.");
|
MqttTrace.Verbose(nameof(MqttClientSessionsManager), "Reusing existing session of client '{0}'.", connectPacket.ClientId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ namespace MQTTnet.Core.Server
|
|||||||
clientSession = new MqttClientSession(connectPacket.ClientId, _options, DispatchPublishPacket);
|
clientSession = new MqttClientSession(connectPacket.ClientId, _options, DispatchPublishPacket);
|
||||||
_clientSessions[connectPacket.ClientId] = clientSession;
|
_clientSessions[connectPacket.ClientId] = clientSession;
|
||||||
|
|
||||||
MqttTrace.Verbose(nameof(MqttClientSessionsManager), $"Created a new session for client '{connectPacket.ClientId}'.");
|
MqttTrace.Verbose(nameof(MqttClientSessionsManager), "Created a new session for client '{0}'.", connectPacket.ClientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new GetOrCreateClientSessionResult { IsExistingSession = isExistingSession, Session = clientSession };
|
return new GetOrCreateClientSessionResult { IsExistingSession = isExistingSession, Session = clientSession };
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ namespace MQTTnet.Core.Server
|
|||||||
|
|
||||||
private void OnClientConnected(object sender, MqttClientConnectedEventArgs eventArgs)
|
private void OnClientConnected(object sender, MqttClientConnectedEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
MqttTrace.Information(nameof(MqttServer), $"Client '{eventArgs.Identifier}': Connected.");
|
MqttTrace.Information(nameof(MqttServer), "Client '{0}': Connected.", eventArgs.Identifier);
|
||||||
ClientConnected?.Invoke(this, eventArgs);
|
ClientConnected?.Invoke(this, eventArgs);
|
||||||
|
|
||||||
Task.Run(() => _clientSessionsManager.RunClientSessionAsync(eventArgs), _cancellationTokenSource.Token);
|
Task.Run(() => _clientSessionsManager.RunClientSessionAsync(eventArgs), _cancellationTokenSource.Token);
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace MQTTnet.TestApp.NetCore
|
|||||||
Server = "localhost",
|
Server = "localhost",
|
||||||
ClientId = "XYZ",
|
ClientId = "XYZ",
|
||||||
CleanSession = true,
|
CleanSession = true,
|
||||||
ConnectionType = ConnectionTypes.WS
|
ConnectionType = MqttConnectionType.Ws
|
||||||
};
|
};
|
||||||
|
|
||||||
var client = new MqttClientFactory().CreateMqttClient(options);
|
var client = new MqttClientFactory().CreateMqttClient(options);
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ namespace MQTTnet.Core.Tests
|
|||||||
|
|
||||||
public async Task ConnectAsync(MqttClientOptions options, TimeSpan timeout)
|
public async Task ConnectAsync(MqttClientOptions options, TimeSpan timeout)
|
||||||
{
|
{
|
||||||
await Task.FromResult(0).ConfigureAwait(false);
|
await Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DisconnectAsync()
|
public async Task DisconnectAsync()
|
||||||
{
|
{
|
||||||
await Task.FromResult(0).ConfigureAwait(false);
|
await Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendPacketAsync(MqttBasePacket packet, TimeSpan timeout)
|
public async Task SendPacketAsync(MqttBasePacket packet, TimeSpan timeout)
|
||||||
@@ -31,14 +31,14 @@ namespace MQTTnet.Core.Tests
|
|||||||
ThrowIfPartnerIsNull();
|
ThrowIfPartnerIsNull();
|
||||||
|
|
||||||
Partner.SendPacketInternal(packet);
|
Partner.SendPacketInternal(packet);
|
||||||
await Task.FromResult(0).ConfigureAwait(false);
|
await Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<MqttBasePacket> ReceivePacketAsync(TimeSpan timeout)
|
public async Task<MqttBasePacket> ReceivePacketAsync(TimeSpan timeout)
|
||||||
{
|
{
|
||||||
ThrowIfPartnerIsNull();
|
ThrowIfPartnerIsNull();
|
||||||
|
|
||||||
return await Task.Run(() => _incomingPackets.Take()).ConfigureAwait(false);
|
return await Task.Run(() => _incomingPackets.Take());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendPacketInternal(MqttBasePacket packet)
|
private void SendPacketInternal(MqttBasePacket packet)
|
||||||
|
|||||||
Reference in New Issue
Block a user