Browse Source

Refactor options

release/3.x.x
Christian Kratky 7 years ago
parent
commit
67267c05fd
40 changed files with 292 additions and 198 deletions
  1. +1
    -0
      Build/MQTTnet.nuspec
  2. +27
    -0
      Frameworks/MQTTnet.NetFramework/Implementations/MqttCommunicationAdapterFactory.cs
  3. +8
    -8
      Frameworks/MQTTnet.NetFramework/Implementations/MqttTcpChannel.cs
  4. +12
    -10
      Frameworks/MQTTnet.NetFramework/Implementations/MqttWebSocketChannel.cs
  5. +1
    -0
      Frameworks/MQTTnet.NetFramework/MQTTnet.NetFramework.csproj
  6. +1
    -18
      Frameworks/MQTTnet.NetFramework/MqttClientFactory.cs
  7. +27
    -0
      Frameworks/MQTTnet.NetStandard/Implementations/MqttCommunicationAdapterFactory.cs
  8. +8
    -7
      Frameworks/MQTTnet.NetStandard/Implementations/MqttTcpChannel.cs
  9. +9
    -8
      Frameworks/MQTTnet.NetStandard/Implementations/MqttWebSocketChannel.cs
  10. +1
    -18
      Frameworks/MQTTnet.NetStandard/MqttClientFactory.cs
  11. +27
    -0
      Frameworks/MQTTnet.UniversalWindows/Implementations/MqttCommunicationAdapterFactory.cs
  12. +9
    -9
      Frameworks/MQTTnet.UniversalWindows/Implementations/MqttTcpChannel.cs
  13. +9
    -8
      Frameworks/MQTTnet.UniversalWindows/Implementations/MqttWebSocketChannel.cs
  14. +1
    -0
      Frameworks/MQTTnet.UniversalWindows/MQTTnet.UniversalWindows.csproj
  15. +1
    -18
      Frameworks/MQTTnet.UniversalWindows/MqttClientFactory.cs
  16. +1
    -2
      MQTTnet.Core/Adapter/IMqttCommunicationAdapter.cs
  17. +2
    -2
      MQTTnet.Core/Adapter/MqttChannelCommunicationAdapter.cs
  18. +1
    -2
      MQTTnet.Core/Channel/IMqttCommunicationChannel.cs
  19. +1
    -1
      MQTTnet.Core/Client/IMqttClient.cs
  20. +9
    -0
      MQTTnet.Core/Client/IMqttCommunicationAdapterFactory.cs
  21. +13
    -10
      MQTTnet.Core/Client/MqttClient.cs
  22. +3
    -7
      MQTTnet.Core/Client/MqttClientOptions.cs
  23. +9
    -0
      MQTTnet.Core/Client/MqttClientTcpOptions.cs
  24. +2
    -2
      MQTTnet.Core/Client/MqttClientTcpOptionsExtensions.cs
  25. +7
    -0
      MQTTnet.Core/Client/MqttClientWebSocketOptions.cs
  26. +0
    -8
      MQTTnet.Core/Client/MqttConnectionType.cs
  27. +3
    -0
      MQTTnet.Core/Server/MqttClientPendingMessagesQueue.cs
  28. +20
    -18
      MQTTnet.Core/Server/MqttClientSession.cs
  29. +2
    -3
      MQTTnet.Core/Server/MqttClientSessionsManager.cs
  30. +1
    -1
      MQTTnet.sln
  31. +1
    -1
      README.md
  32. +20
    -0
      Tests/MQTTnet.Core.Tests/MqttCommunicationAdapterFactory.cs
  33. +1
    -2
      Tests/MQTTnet.Core.Tests/MqttPacketSerializerTests.cs
  34. +0
    -1
      Tests/MQTTnet.Core.Tests/MqttServerTests.cs
  35. +1
    -2
      Tests/MQTTnet.Core.Tests/TestMqttCommunicationAdapter.cs
  36. +7
    -7
      Tests/MQTTnet.Core.Tests/TestMqttServerAdapter.cs
  37. +5
    -6
      Tests/MQTTnet.TestApp.NetCore/Program.cs
  38. +3
    -3
      Tests/MQTTnet.TestApp.NetFramework/PerformanceTest.cs
  39. +11
    -6
      Tests/MQTTnet.TestApp.NetFramework/Program.cs
  40. +27
    -10
      Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs

+ 1
- 0
Build/MQTTnet.nuspec View File

@@ -16,6 +16,7 @@
* [Server] The client connection is now closed if sending of one pending application message has failed * [Server] The client connection is now closed if sending of one pending application message has failed
* [Server] Fixed handling of _Dup_ flag (Thanks to haeberle) * [Server] Fixed handling of _Dup_ flag (Thanks to haeberle)
* [Core] Optimized exception handling * [Core] Optimized exception handling
* [Core] Mono is now also supported (Thanks to JTrotta)
</releaseNotes> </releaseNotes>
<copyright>Copyright Christian Kratky 2016-2017</copyright> <copyright>Copyright Christian Kratky 2016-2017</copyright>
<tags>MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M</tags> <tags>MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M</tags>


+ 27
- 0
Frameworks/MQTTnet.NetFramework/Implementations/MqttCommunicationAdapterFactory.cs View File

@@ -0,0 +1,27 @@
using System;
using MQTTnet.Core.Adapter;
using MQTTnet.Core.Client;
using MQTTnet.Core.Serializer;

namespace MQTTnet.Implementations
{
public class MqttCommunicationAdapterFactory : IMqttCommunicationAdapterFactory
{
public IMqttCommunicationAdapter CreateMqttCommunicationAdapter(MqttClientOptions options)
{
if (options == null) throw new ArgumentNullException(nameof(options));

if (options is MqttClientTcpOptions tcpOptions)
{
return new MqttChannelCommunicationAdapter(new MqttTcpChannel(tcpOptions), new MqttPacketSerializer { ProtocolVersion = options.ProtocolVersion });
}

if (options is MqttClientWebSocketOptions webSocketOptions)
{
return new MqttChannelCommunicationAdapter(new MqttWebSocketChannel(webSocketOptions), new MqttPacketSerializer { ProtocolVersion = options.ProtocolVersion });
}

throw new NotSupportedException();
}
}
}

+ 8
- 8
Frameworks/MQTTnet.NetFramework/Implementations/MqttTcpChannel.cs View File

@@ -12,6 +12,8 @@ namespace MQTTnet.Implementations
{ {
public sealed class MqttTcpChannel : IMqttCommunicationChannel, IDisposable public sealed class MqttTcpChannel : IMqttCommunicationChannel, IDisposable
{ {
private readonly MqttClientTcpOptions _options;

// ReSharper disable once MemberCanBePrivate.Global // ReSharper disable once MemberCanBePrivate.Global
// ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global
public static int BufferSize { get; set; } = 4096 * 20; // Can be changed for fine tuning by library user. public static int BufferSize { get; set; } = 4096 * 20; // Can be changed for fine tuning by library user.
@@ -22,9 +24,9 @@ namespace MQTTnet.Implementations
/// <summary> /// <summary>
/// called on client sockets are created in connect /// called on client sockets are created in connect
/// </summary> /// </summary>
public MqttTcpChannel()
public MqttTcpChannel(MqttClientTcpOptions options)
{ {
_options = options ?? throw new ArgumentNullException(nameof(options));
} }


/// <summary> /// <summary>
@@ -42,22 +44,20 @@ namespace MQTTnet.Implementations
public Stream ReceiveStream { get; private set; } public Stream ReceiveStream { get; private set; }
public Stream RawReceiveStream { get; private set; } public Stream RawReceiveStream { get; private set; }


public async Task ConnectAsync(MqttClientOptions options)
public async Task ConnectAsync()
{ {
if (options == null) throw new ArgumentNullException(nameof(options));

if (_socket == null) if (_socket == null)
{ {
_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).ConfigureAwait(false);


if (options.TlsOptions.UseTls)
if (_options.TlsOptions.UseTls)
{ {
_sslStream = new SslStream(new NetworkStream(_socket, true)); _sslStream = new SslStream(new NetworkStream(_socket, true));


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);
} }


CreateStreams(_socket, _sslStream); CreateStreams(_socket, _sslStream);


+ 12
- 10
Frameworks/MQTTnet.NetFramework/Implementations/MqttWebSocketChannel.cs View File

@@ -10,27 +10,29 @@ namespace MQTTnet.Implementations
{ {
public sealed class MqttWebSocketChannel : IMqttCommunicationChannel, IDisposable public sealed class MqttWebSocketChannel : IMqttCommunicationChannel, IDisposable
{ {
private readonly MqttClientWebSocketOptions _options;

private ClientWebSocket _webSocket; private ClientWebSocket _webSocket;


public MqttWebSocketChannel(MqttClientWebSocketOptions options)
{
_options = options ?? throw new ArgumentNullException(nameof(options));
}

public Stream RawReceiveStream { get; private set; } public Stream RawReceiveStream { get; private set; }
public Stream SendStream => RawReceiveStream; public Stream SendStream => RawReceiveStream;
public Stream ReceiveStream => RawReceiveStream; public Stream ReceiveStream => RawReceiveStream;

public async Task ConnectAsync(MqttClientOptions options)
public async Task ConnectAsync()
{ {
var uri = options.Server;
var uri = _options.Uri;
if (!uri.StartsWith("ws://", StringComparison.OrdinalIgnoreCase)) if (!uri.StartsWith("ws://", StringComparison.OrdinalIgnoreCase))
{ {
uri = "ws://" + uri; uri = "ws://" + uri;
} }

if (options.Port.HasValue)
{
uri += ":" + options.Port;
}
_webSocket = new ClientWebSocket(); _webSocket = new ClientWebSocket();
_webSocket.Options.KeepAliveInterval = options.KeepAlivePeriod;
_webSocket.Options.KeepAliveInterval = _options.KeepAlivePeriod;
await _webSocket.ConnectAsync(new Uri(uri), CancellationToken.None).ConfigureAwait(false); await _webSocket.ConnectAsync(new Uri(uri), CancellationToken.None).ConfigureAwait(false);
RawReceiveStream = new WebSocketStream(_webSocket); RawReceiveStream = new WebSocketStream(_webSocket);
} }


+ 1
- 0
Frameworks/MQTTnet.NetFramework/MQTTnet.NetFramework.csproj View File

@@ -100,6 +100,7 @@
<Reference Include="System.Core" /> <Reference Include="System.Core" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Implementations\MqttCommunicationAdapterFactory.cs" />
<Compile Include="Implementations\MqttWebSocketChannel.cs" /> <Compile Include="Implementations\MqttWebSocketChannel.cs" />
<Compile Include="Implementations\WebSocketStream.cs" /> <Compile Include="Implementations\WebSocketStream.cs" />
<Compile Include="MqttClientFactory.cs" /> <Compile Include="MqttClientFactory.cs" />


+ 1
- 18
Frameworks/MQTTnet.NetFramework/MqttClientFactory.cs View File

@@ -1,8 +1,5 @@
using System; using System;
using MQTTnet.Core.Adapter;
using MQTTnet.Core.Channel;
using MQTTnet.Core.Client; using MQTTnet.Core.Client;
using MQTTnet.Core.Serializer;
using MQTTnet.Implementations; using MQTTnet.Implementations;


namespace MQTTnet namespace MQTTnet
@@ -13,21 +10,7 @@ namespace MQTTnet
{ {
if (options == null) throw new ArgumentNullException(nameof(options)); if (options == null) throw new ArgumentNullException(nameof(options));


return new MqttClient(options, new MqttChannelCommunicationAdapter(GetMqttCommunicationChannel(options), new MqttPacketSerializer()));
}

private static IMqttCommunicationChannel GetMqttCommunicationChannel(MqttClientOptions options)
{
switch (options.ConnectionType)
{
case MqttConnectionType.Tcp:
return new MqttTcpChannel();
case MqttConnectionType.Ws:
return new MqttWebSocketChannel();

default:
throw new NotSupportedException();
}
return new MqttClient(new MqttCommunicationAdapterFactory());
} }
} }
} }

+ 27
- 0
Frameworks/MQTTnet.NetStandard/Implementations/MqttCommunicationAdapterFactory.cs View File

@@ -0,0 +1,27 @@
using System;
using MQTTnet.Core.Adapter;
using MQTTnet.Core.Client;
using MQTTnet.Core.Serializer;

namespace MQTTnet.Implementations
{
public class MqttCommunicationAdapterFactory : IMqttCommunicationAdapterFactory
{
public IMqttCommunicationAdapter CreateMqttCommunicationAdapter(MqttClientOptions options)
{
if (options == null) throw new ArgumentNullException(nameof(options));

if (options is MqttClientTcpOptions tcpOptions)
{
return new MqttChannelCommunicationAdapter(new MqttTcpChannel(tcpOptions), new MqttPacketSerializer { ProtocolVersion = options.ProtocolVersion });
}

if (options is MqttClientWebSocketOptions webSocketOptions)
{
return new MqttChannelCommunicationAdapter(new MqttWebSocketChannel(webSocketOptions), new MqttPacketSerializer { ProtocolVersion = options.ProtocolVersion });
}

throw new NotSupportedException();
}
}
}

+ 8
- 7
Frameworks/MQTTnet.NetStandard/Implementations/MqttTcpChannel.cs View File

@@ -12,14 +12,17 @@ namespace MQTTnet.Implementations
{ {
public sealed class MqttTcpChannel : IMqttCommunicationChannel, IDisposable public sealed class MqttTcpChannel : IMqttCommunicationChannel, IDisposable
{ {
private readonly MqttClientTcpOptions _options;

private Socket _socket; private Socket _socket;
private SslStream _sslStream; private SslStream _sslStream;
/// <summary> /// <summary>
/// called on client sockets are created in connect /// called on client sockets are created in connect
/// </summary> /// </summary>
public MqttTcpChannel()
public MqttTcpChannel(MqttClientTcpOptions options)
{ {
_options = options ?? throw new ArgumentNullException(nameof(options));
} }


/// <summary> /// <summary>
@@ -37,22 +40,20 @@ namespace MQTTnet.Implementations
public Stream ReceiveStream { get; private set; } public Stream ReceiveStream { get; private set; }
public Stream RawReceiveStream => ReceiveStream; public Stream RawReceiveStream => ReceiveStream;
public async Task ConnectAsync(MqttClientOptions options)
public async Task ConnectAsync()
{ {
if (options == null) throw new ArgumentNullException(nameof(options));

if (_socket == null) if (_socket == null)
{ {
_socket = new Socket(SocketType.Stream, ProtocolType.Tcp); _socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
} }


await _socket.ConnectAsync(options.Server, options.GetPort()).ConfigureAwait(false);
await _socket.ConnectAsync(_options.Server, _options.GetPort()).ConfigureAwait(false);


if (options.TlsOptions.UseTls)
if (_options.TlsOptions.UseTls)
{ {
_sslStream = new SslStream(new NetworkStream(_socket, true)); _sslStream = new SslStream(new NetworkStream(_socket, true));
ReceiveStream = _sslStream; ReceiveStream = _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);
} }
else else
{ {


+ 9
- 8
Frameworks/MQTTnet.NetStandard/Implementations/MqttWebSocketChannel.cs View File

@@ -10,27 +10,28 @@ namespace MQTTnet.Implementations
{ {
public sealed class MqttWebSocketChannel : IMqttCommunicationChannel, IDisposable public sealed class MqttWebSocketChannel : IMqttCommunicationChannel, IDisposable
{ {
private readonly MqttClientWebSocketOptions _options;
private ClientWebSocket _webSocket; private ClientWebSocket _webSocket;


public MqttWebSocketChannel(MqttClientWebSocketOptions options)
{
_options = options ?? throw new ArgumentNullException(nameof(options));
}

public Stream SendStream => RawReceiveStream; public Stream SendStream => RawReceiveStream;
public Stream ReceiveStream => RawReceiveStream; public Stream ReceiveStream => RawReceiveStream;
public Stream RawReceiveStream { get; private set; } public Stream RawReceiveStream { get; private set; }


public async Task ConnectAsync(MqttClientOptions options)
public async Task ConnectAsync()
{ {
var uri = options.Server;
var uri = _options.Uri;
if (!uri.StartsWith("ws://", StringComparison.OrdinalIgnoreCase)) if (!uri.StartsWith("ws://", StringComparison.OrdinalIgnoreCase))
{ {
uri = "ws://" + uri; uri = "ws://" + uri;
} }


if (options.Port.HasValue)
{
uri += ":" + options.Port;
}
_webSocket = new ClientWebSocket(); _webSocket = new ClientWebSocket();
_webSocket.Options.KeepAliveInterval = options.KeepAlivePeriod;
_webSocket.Options.KeepAliveInterval = _options.KeepAlivePeriod;
await _webSocket.ConnectAsync(new Uri(uri), CancellationToken.None); await _webSocket.ConnectAsync(new Uri(uri), CancellationToken.None);
RawReceiveStream = new WebSocketStream(_webSocket); RawReceiveStream = new WebSocketStream(_webSocket);
} }


+ 1
- 18
Frameworks/MQTTnet.NetStandard/MqttClientFactory.cs View File

@@ -1,8 +1,5 @@
using System; using System;
using MQTTnet.Core.Adapter;
using MQTTnet.Core.Channel;
using MQTTnet.Core.Client; using MQTTnet.Core.Client;
using MQTTnet.Core.Serializer;
using MQTTnet.Implementations; using MQTTnet.Implementations;


namespace MQTTnet namespace MQTTnet
@@ -13,21 +10,7 @@ namespace MQTTnet
{ {
if (options == null) throw new ArgumentNullException(nameof(options)); if (options == null) throw new ArgumentNullException(nameof(options));


return new MqttClient(options, new MqttChannelCommunicationAdapter(GetMqttCommunicationChannel(options), new MqttPacketSerializer()));
}

private static IMqttCommunicationChannel GetMqttCommunicationChannel(MqttClientOptions options)
{
switch (options.ConnectionType)
{
case MqttConnectionType.Tcp:
return new MqttTcpChannel();
case MqttConnectionType.Ws:
return new MqttWebSocketChannel();

default:
throw new NotSupportedException();
}
return new MqttClient(new MqttCommunicationAdapterFactory());
} }
} }
} }

+ 27
- 0
Frameworks/MQTTnet.UniversalWindows/Implementations/MqttCommunicationAdapterFactory.cs View File

@@ -0,0 +1,27 @@
using System;
using MQTTnet.Core.Adapter;
using MQTTnet.Core.Client;
using MQTTnet.Core.Serializer;

namespace MQTTnet.Implementations
{
public class MqttCommunicationAdapterFactory : IMqttCommunicationAdapterFactory
{
public IMqttCommunicationAdapter CreateMqttCommunicationAdapter(MqttClientOptions options)
{
if (options == null) throw new ArgumentNullException(nameof(options));

if (options is MqttClientTcpOptions tcpOptions)
{
return new MqttChannelCommunicationAdapter(new MqttTcpChannel(tcpOptions), new MqttPacketSerializer { ProtocolVersion = options.ProtocolVersion });
}

if (options is MqttClientWebSocketOptions webSocketOptions)
{
return new MqttChannelCommunicationAdapter(new MqttWebSocketChannel(webSocketOptions), new MqttPacketSerializer { ProtocolVersion = options.ProtocolVersion });
}

throw new NotSupportedException();
}
}
}

+ 9
- 9
Frameworks/MQTTnet.UniversalWindows/Implementations/MqttTcpChannel.cs View File

@@ -13,10 +13,12 @@ namespace MQTTnet.Implementations
{ {
public sealed class MqttTcpChannel : IMqttCommunicationChannel, IDisposable public sealed class MqttTcpChannel : IMqttCommunicationChannel, IDisposable
{ {
private readonly MqttClientTcpOptions _options;
private StreamSocket _socket; private StreamSocket _socket;


public MqttTcpChannel()
public MqttTcpChannel(MqttClientTcpOptions options)
{ {
_options = options ?? throw new ArgumentNullException(nameof(options));
} }


public MqttTcpChannel(StreamSocket socket) public MqttTcpChannel(StreamSocket socket)
@@ -29,30 +31,28 @@ namespace MQTTnet.Implementations
public Stream ReceiveStream { get; private set; } public Stream ReceiveStream { get; private set; }
public Stream RawReceiveStream { get; private set; } public Stream RawReceiveStream { get; private set; }


public async Task ConnectAsync(MqttClientOptions options)
public async Task ConnectAsync()
{ {
if (options == null) throw new ArgumentNullException(nameof(options));

if (_socket == null) if (_socket == null)
{ {
_socket = new StreamSocket(); _socket = new StreamSocket();
} }


if (!options.TlsOptions.UseTls)
if (!_options.TlsOptions.UseTls)
{ {
await _socket.ConnectAsync(new HostName(options.Server), options.GetPort().ToString());
await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString());
} }
else else
{ {
_socket.Control.ClientCertificate = LoadCertificate(options);
_socket.Control.ClientCertificate = LoadCertificate(_options);


if (!options.TlsOptions.CheckCertificateRevocation)
if (!_options.TlsOptions.CheckCertificateRevocation)
{ {
_socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.IncompleteChain); _socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.IncompleteChain);
_socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.RevocationInformationMissing); _socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.RevocationInformationMissing);
} }


await _socket.ConnectAsync(new HostName(options.Server), options.GetPort().ToString(), SocketProtectionLevel.Tls12);
await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString(), SocketProtectionLevel.Tls12);
} }


CreateStreams(); CreateStreams();


+ 9
- 8
Frameworks/MQTTnet.UniversalWindows/Implementations/MqttWebSocketChannel.cs View File

@@ -10,27 +10,28 @@ namespace MQTTnet.Implementations
{ {
public sealed class MqttWebSocketChannel : IMqttCommunicationChannel, IDisposable public sealed class MqttWebSocketChannel : IMqttCommunicationChannel, IDisposable
{ {
private readonly MqttClientWebSocketOptions _options;
private ClientWebSocket _webSocket = new ClientWebSocket(); private ClientWebSocket _webSocket = new ClientWebSocket();


public MqttWebSocketChannel(MqttClientWebSocketOptions options)
{
_options = options ?? throw new ArgumentNullException(nameof(options));
}

public Stream RawReceiveStream { get; private set; } public Stream RawReceiveStream { get; private set; }
public Stream SendStream => RawReceiveStream; public Stream SendStream => RawReceiveStream;
public Stream ReceiveStream => RawReceiveStream; public Stream ReceiveStream => RawReceiveStream;


public async Task ConnectAsync(MqttClientOptions options)
public async Task ConnectAsync()
{ {
var uri = options.Server;
var uri = _options.Uri;
if (!uri.StartsWith("ws://", StringComparison.OrdinalIgnoreCase)) if (!uri.StartsWith("ws://", StringComparison.OrdinalIgnoreCase))
{ {
uri = "ws://" + uri; uri = "ws://" + uri;
} }


if (options.Port.HasValue)
{
uri += ":" + options.Port;
}
_webSocket = new ClientWebSocket(); _webSocket = new ClientWebSocket();
_webSocket.Options.KeepAliveInterval = options.KeepAlivePeriod;
_webSocket.Options.KeepAliveInterval = _options.KeepAlivePeriod;
await _webSocket.ConnectAsync(new Uri(uri), CancellationToken.None).ConfigureAwait(false); await _webSocket.ConnectAsync(new Uri(uri), CancellationToken.None).ConfigureAwait(false);


RawReceiveStream = new WebSocketStream(_webSocket); RawReceiveStream = new WebSocketStream(_webSocket);


+ 1
- 0
Frameworks/MQTTnet.UniversalWindows/MQTTnet.UniversalWindows.csproj View File

@@ -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\MqttCommunicationAdapterFactory.cs" />
<Compile Include="Implementations\MqttWebSocketChannel.cs" /> <Compile Include="Implementations\MqttWebSocketChannel.cs" />
<Compile Include="MqttClientFactory.cs" /> <Compile Include="MqttClientFactory.cs" />
<Compile Include="Implementations\MqttServerAdapter.cs" /> <Compile Include="Implementations\MqttServerAdapter.cs" />


+ 1
- 18
Frameworks/MQTTnet.UniversalWindows/MqttClientFactory.cs View File

@@ -1,8 +1,5 @@
using System; using System;
using MQTTnet.Core.Adapter;
using MQTTnet.Core.Channel;
using MQTTnet.Core.Client; using MQTTnet.Core.Client;
using MQTTnet.Core.Serializer;
using MQTTnet.Implementations; using MQTTnet.Implementations;


namespace MQTTnet namespace MQTTnet
@@ -13,21 +10,7 @@ namespace MQTTnet
{ {
if (options == null) throw new ArgumentNullException(nameof(options)); if (options == null) throw new ArgumentNullException(nameof(options));


return new MqttClient(options, new MqttChannelCommunicationAdapter(GetMqttCommunicationChannel(options), new MqttPacketSerializer()));
}

private static IMqttCommunicationChannel GetMqttCommunicationChannel(MqttClientOptions options)
{
switch (options.ConnectionType)
{
case MqttConnectionType.Tcp:
return new MqttTcpChannel();
case MqttConnectionType.Ws:
return new MqttWebSocketChannel();

default:
throw new NotSupportedException();
}
return new MqttClient(new MqttCommunicationAdapterFactory());
} }
} }
} }

+ 1
- 2
MQTTnet.Core/Adapter/IMqttCommunicationAdapter.cs View File

@@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MQTTnet.Core.Client;
using MQTTnet.Core.Packets; using MQTTnet.Core.Packets;
using MQTTnet.Core.Serializer; using MQTTnet.Core.Serializer;


@@ -12,7 +11,7 @@ namespace MQTTnet.Core.Adapter
{ {
IMqttPacketSerializer PacketSerializer { get; } IMqttPacketSerializer PacketSerializer { get; }


Task ConnectAsync(TimeSpan timeout, MqttClientOptions options);
Task ConnectAsync(TimeSpan timeout);


Task DisconnectAsync(TimeSpan timeout); Task DisconnectAsync(TimeSpan timeout);




+ 2
- 2
MQTTnet.Core/Adapter/MqttChannelCommunicationAdapter.cs View File

@@ -26,11 +26,11 @@ namespace MQTTnet.Core.Adapter


public IMqttPacketSerializer PacketSerializer { get; } public IMqttPacketSerializer PacketSerializer { get; }


public async Task ConnectAsync(TimeSpan timeout, MqttClientOptions options)
public async Task ConnectAsync(TimeSpan timeout)
{ {
try try
{ {
await _channel.ConnectAsync(options).TimeoutAfter(timeout).ConfigureAwait(false);
await _channel.ConnectAsync().TimeoutAfter(timeout).ConfigureAwait(false);
} }
catch (TaskCanceledException) catch (TaskCanceledException)
{ {


+ 1
- 2
MQTTnet.Core/Channel/IMqttCommunicationChannel.cs View File

@@ -1,5 +1,4 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using MQTTnet.Core.Client;
using System.IO; using System.IO;


namespace MQTTnet.Core.Channel namespace MQTTnet.Core.Channel
@@ -10,7 +9,7 @@ namespace MQTTnet.Core.Channel
Stream ReceiveStream { get; } Stream ReceiveStream { get; }
Stream RawReceiveStream { get; } Stream RawReceiveStream { get; }


Task ConnectAsync(MqttClientOptions options);
Task ConnectAsync();
Task DisconnectAsync(); Task DisconnectAsync();
} }
} }

+ 1
- 1
MQTTnet.Core/Client/IMqttClient.cs View File

@@ -13,7 +13,7 @@ namespace MQTTnet.Core.Client
event EventHandler Connected; event EventHandler Connected;
event EventHandler Disconnected; event EventHandler Disconnected;


Task ConnectAsync(MqttApplicationMessage willApplicationMessage = null);
Task ConnectAsync(MqttClientOptions options);
Task DisconnectAsync(); Task DisconnectAsync();


Task<IList<MqttSubscribeResult>> SubscribeAsync(IEnumerable<TopicFilter> topicFilters); Task<IList<MqttSubscribeResult>> SubscribeAsync(IEnumerable<TopicFilter> topicFilters);


+ 9
- 0
MQTTnet.Core/Client/IMqttCommunicationAdapterFactory.cs View File

@@ -0,0 +1,9 @@
using MQTTnet.Core.Adapter;

namespace MQTTnet.Core.Client
{
public interface IMqttCommunicationAdapterFactory
{
IMqttCommunicationAdapter CreateMqttCommunicationAdapter(MqttClientOptions options);
}
}

+ 13
- 10
MQTTnet.Core/Client/MqttClient.cs View File

@@ -16,19 +16,17 @@ namespace MQTTnet.Core.Client
{ {
private readonly HashSet<ushort> _unacknowledgedPublishPackets = new HashSet<ushort>(); private readonly HashSet<ushort> _unacknowledgedPublishPackets = new HashSet<ushort>();
private readonly MqttPacketDispatcher _packetDispatcher = new MqttPacketDispatcher(); private readonly MqttPacketDispatcher _packetDispatcher = new MqttPacketDispatcher();
private readonly MqttClientOptions _options;
private readonly IMqttCommunicationAdapter _adapter;
private readonly IMqttCommunicationAdapterFactory _communicationChannelFactory;


private MqttClientOptions _options;
private bool _isReceivingPackets; private bool _isReceivingPackets;
private int _latestPacketIdentifier; private int _latestPacketIdentifier;
private CancellationTokenSource _cancellationTokenSource; private CancellationTokenSource _cancellationTokenSource;
private IMqttCommunicationAdapter _adapter;


public MqttClient(MqttClientOptions options, IMqttCommunicationAdapter adapter)
public MqttClient(IMqttCommunicationAdapterFactory communicationChannelFactory)
{ {
_options = options ?? throw new ArgumentNullException(nameof(options));
_adapter = adapter ?? throw new ArgumentNullException(nameof(adapter));

_adapter.PacketSerializer.ProtocolVersion = options.ProtocolVersion;
_communicationChannelFactory = communicationChannelFactory;
} }


public event EventHandler Connected; public event EventHandler Connected;
@@ -37,22 +35,27 @@ namespace MQTTnet.Core.Client


public bool IsConnected => _cancellationTokenSource != null && !_cancellationTokenSource.IsCancellationRequested; public bool IsConnected => _cancellationTokenSource != null && !_cancellationTokenSource.IsCancellationRequested;


public async Task ConnectAsync(MqttApplicationMessage willApplicationMessage = null)
public async Task ConnectAsync(MqttClientOptions options)
{ {
if (options == null) throw new ArgumentNullException(nameof(options));

ThrowIfConnected("It is not allowed to connect with a server after the connection is established."); ThrowIfConnected("It is not allowed to connect with a server after the connection is established.");


try try
{ {
_options = options;
_cancellationTokenSource = new CancellationTokenSource(); _cancellationTokenSource = new CancellationTokenSource();
_latestPacketIdentifier = 0; _latestPacketIdentifier = 0;
_packetDispatcher.Reset(); _packetDispatcher.Reset();


_adapter = _communicationChannelFactory.CreateMqttCommunicationAdapter(options);
MqttTrace.Verbose(nameof(MqttClient), "Trying to connect with server."); MqttTrace.Verbose(nameof(MqttClient), "Trying to connect with server.");
await _adapter.ConnectAsync(_options.DefaultCommunicationTimeout, _options).ConfigureAwait(false);
await _adapter.ConnectAsync(_options.DefaultCommunicationTimeout).ConfigureAwait(false);
MqttTrace.Verbose(nameof(MqttClient), "Connection with server established."); MqttTrace.Verbose(nameof(MqttClient), "Connection with server established.");


await SetupIncomingPacketProcessingAsync(); await SetupIncomingPacketProcessingAsync();
await AuthenticateAsync(willApplicationMessage);
await AuthenticateAsync(options.WillMessage);


MqttTrace.Verbose(nameof(MqttClient), "MQTT connection with server established."); MqttTrace.Verbose(nameof(MqttClient), "MQTT connection with server established.");




+ 3
- 7
MQTTnet.Core/Client/MqttClientOptions.cs View File

@@ -3,14 +3,12 @@ using MQTTnet.Core.Serializer;


namespace MQTTnet.Core.Client namespace MQTTnet.Core.Client
{ {
public sealed class MqttClientOptions
public abstract class MqttClientOptions
{ {
public string Server { get; set; }

public int? Port { get; set; }

public MqttClientTlsOptions TlsOptions { get; set; } = new MqttClientTlsOptions(); public MqttClientTlsOptions TlsOptions { get; set; } = new MqttClientTlsOptions();


public MqttApplicationMessage WillMessage { get; set; }

public string UserName { get; set; } public string UserName { get; set; }


public string Password { get; set; } public string Password { get; set; }
@@ -24,7 +22,5 @@ namespace MQTTnet.Core.Client
public TimeSpan DefaultCommunicationTimeout { get; set; } = TimeSpan.FromSeconds(10); public TimeSpan DefaultCommunicationTimeout { get; set; } = TimeSpan.FromSeconds(10);


public MqttProtocolVersion ProtocolVersion { get; set; } = MqttProtocolVersion.V311; public MqttProtocolVersion ProtocolVersion { get; set; } = MqttProtocolVersion.V311;

public MqttConnectionType ConnectionType { get; set; } = MqttConnectionType.Tcp;
} }
} }

+ 9
- 0
MQTTnet.Core/Client/MqttClientTcpOptions.cs View File

@@ -0,0 +1,9 @@
namespace MQTTnet.Core.Client
{
public class MqttClientTcpOptions : MqttClientOptions
{
public string Server { get; set; }

public int? Port { get; set; }
}
}

MQTTnet.Core/Client/MqttClientOptionsExtensions.cs → MQTTnet.Core/Client/MqttClientTcpOptionsExtensions.cs View File

@@ -2,9 +2,9 @@


namespace MQTTnet.Core.Client namespace MQTTnet.Core.Client
{ {
public static class MqttClientOptionsExtensions
public static class MqttClientTcpOptionsExtensions
{ {
public static int GetPort(this MqttClientOptions options)
public static int GetPort(this MqttClientTcpOptions options)
{ {
if (options == null) throw new ArgumentNullException(nameof(options)); if (options == null) throw new ArgumentNullException(nameof(options));



+ 7
- 0
MQTTnet.Core/Client/MqttClientWebSocketOptions.cs View File

@@ -0,0 +1,7 @@
namespace MQTTnet.Core.Client
{
public class MqttClientWebSocketOptions : MqttClientOptions
{
public string Uri { get; set; }
}
}

+ 0
- 8
MQTTnet.Core/Client/MqttConnectionType.cs View File

@@ -1,8 +0,0 @@
namespace MQTTnet.Core.Client
{
public enum MqttConnectionType
{
Tcp,
Ws
}
}

+ 3
- 0
MQTTnet.Core/Server/MqttClientPendingMessagesQueue.cs View File

@@ -72,6 +72,9 @@ namespace MQTTnet.Core.Server
{ {
MqttTrace.Warning(nameof(MqttClientPendingMessagesQueue), exception, "Sending publish packet failed due to communication exception."); MqttTrace.Warning(nameof(MqttClientPendingMessagesQueue), exception, "Sending publish packet failed due to communication exception.");
} }
if (exception is OperationCanceledException)
{
}
else else
{ {
MqttTrace.Error(nameof(MqttClientPendingMessagesQueue), exception, "Sending publish packet failed."); MqttTrace.Error(nameof(MqttClientPendingMessagesQueue), exception, "Sending publish packet failed.");


+ 20
- 18
MQTTnet.Core/Server/MqttClientSession.cs View File

@@ -8,6 +8,7 @@ using MQTTnet.Core.Exceptions;
using MQTTnet.Core.Internal; using MQTTnet.Core.Internal;
using MQTTnet.Core.Packets; using MQTTnet.Core.Packets;
using MQTTnet.Core.Protocol; using MQTTnet.Core.Protocol;
using MQTTnet.Core.Serializer;


namespace MQTTnet.Core.Server namespace MQTTnet.Core.Server
{ {
@@ -19,7 +20,8 @@ namespace MQTTnet.Core.Server
private readonly MqttClientSessionsManager _mqttClientSessionsManager; private readonly MqttClientSessionsManager _mqttClientSessionsManager;
private readonly MqttClientPendingMessagesQueue _pendingMessagesQueue; private readonly MqttClientPendingMessagesQueue _pendingMessagesQueue;
private readonly MqttServerOptions _options; private readonly MqttServerOptions _options;

private IMqttCommunicationAdapter _adapter;
private CancellationTokenSource _cancellationTokenSource; private CancellationTokenSource _cancellationTokenSource;
private MqttApplicationMessage _willMessage; private MqttApplicationMessage _willMessage;


@@ -33,9 +35,9 @@ namespace MQTTnet.Core.Server


public string ClientId { get; } public string ClientId { get; }


public bool IsConnected => Adapter != null;
public MqttProtocolVersion? ProtocolVersion => _adapter?.PacketSerializer.ProtocolVersion;


public IMqttCommunicationAdapter Adapter { get; private set; }
public bool IsConnected => _adapter != null;


public async Task RunAsync(MqttApplicationMessage willMessage, IMqttCommunicationAdapter adapter) public async Task RunAsync(MqttApplicationMessage willMessage, IMqttCommunicationAdapter adapter)
{ {
@@ -45,7 +47,7 @@ namespace MQTTnet.Core.Server


try try
{ {
Adapter = adapter;
_adapter = adapter;
_cancellationTokenSource = new CancellationTokenSource(); _cancellationTokenSource = new CancellationTokenSource();


_pendingMessagesQueue.Start(adapter, _cancellationTokenSource.Token); _pendingMessagesQueue.Start(adapter, _cancellationTokenSource.Token);
@@ -75,7 +77,7 @@ namespace MQTTnet.Core.Server
_cancellationTokenSource?.Dispose(); _cancellationTokenSource?.Dispose();
_cancellationTokenSource = null; _cancellationTokenSource = null;


Adapter = null;
_adapter = null;


MqttTrace.Information(nameof(MqttClientSession), "Client '{0}': Disconnected.", ClientId); MqttTrace.Information(nameof(MqttClientSession), "Client '{0}': Disconnected.", ClientId);
} }
@@ -106,7 +108,7 @@ namespace MQTTnet.Core.Server
while (!cancellationToken.IsCancellationRequested) while (!cancellationToken.IsCancellationRequested)
{ {
var packet = await adapter.ReceivePacketAsync(TimeSpan.Zero, cancellationToken).ConfigureAwait(false); var packet = await adapter.ReceivePacketAsync(TimeSpan.Zero, cancellationToken).ConfigureAwait(false);
await ProcessReceivedPacketAsync(packet).ConfigureAwait(false);
await ProcessReceivedPacketAsync(adapter, packet).ConfigureAwait(false);
} }
} }
catch (OperationCanceledException) catch (OperationCanceledException)
@@ -124,28 +126,28 @@ namespace MQTTnet.Core.Server
} }
} }


private async Task ProcessReceivedPacketAsync(MqttBasePacket packet)
private async Task ProcessReceivedPacketAsync(IMqttCommunicationAdapter adapter, MqttBasePacket packet)
{ {
if (packet is MqttSubscribePacket subscribePacket) if (packet is MqttSubscribePacket subscribePacket)
{ {
await Adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, _subscriptionsManager.Subscribe(subscribePacket));
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, _subscriptionsManager.Subscribe(subscribePacket));
EnqueueRetainedMessages(subscribePacket); EnqueueRetainedMessages(subscribePacket);
} }
else if (packet is MqttUnsubscribePacket unsubscribePacket) else if (packet is MqttUnsubscribePacket unsubscribePacket)
{ {
await Adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, _subscriptionsManager.Unsubscribe(unsubscribePacket));
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, _subscriptionsManager.Unsubscribe(unsubscribePacket));
} }
else if (packet is MqttPublishPacket publishPacket) else if (packet is MqttPublishPacket publishPacket)
{ {
await HandleIncomingPublishPacketAsync(publishPacket);
await HandleIncomingPublishPacketAsync(adapter, publishPacket);
} }
else if (packet is MqttPubRelPacket pubRelPacket) else if (packet is MqttPubRelPacket pubRelPacket)
{ {
await HandleIncomingPubRelPacketAsync(pubRelPacket);
await HandleIncomingPubRelPacketAsync(adapter, pubRelPacket);
} }
else if (packet is MqttPubRecPacket pubRecPacket) else if (packet is MqttPubRecPacket pubRecPacket)
{ {
await Adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, pubRecPacket.CreateResponse<MqttPubRelPacket>());
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, pubRecPacket.CreateResponse<MqttPubRelPacket>());
} }
else if (packet is MqttPubAckPacket || packet is MqttPubCompPacket) else if (packet is MqttPubAckPacket || packet is MqttPubCompPacket)
{ {
@@ -153,7 +155,7 @@ namespace MQTTnet.Core.Server
} }
else if (packet is MqttPingReqPacket) else if (packet is MqttPingReqPacket)
{ {
await Adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, new MqttPingRespPacket());
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, new MqttPingRespPacket());
} }
else if (packet is MqttDisconnectPacket || packet is MqttConnectPacket) else if (packet is MqttDisconnectPacket || packet is MqttConnectPacket)
{ {
@@ -175,7 +177,7 @@ namespace MQTTnet.Core.Server
} }
} }


private async Task HandleIncomingPublishPacketAsync(MqttPublishPacket publishPacket)
private async Task HandleIncomingPublishPacketAsync(IMqttCommunicationAdapter adapter, MqttPublishPacket publishPacket)
{ {
if (publishPacket.Retain) if (publishPacket.Retain)
{ {
@@ -191,7 +193,7 @@ namespace MQTTnet.Core.Server
if (publishPacket.QualityOfServiceLevel == MqttQualityOfServiceLevel.AtLeastOnce) if (publishPacket.QualityOfServiceLevel == MqttQualityOfServiceLevel.AtLeastOnce)
{ {
_mqttClientSessionsManager.DispatchPublishPacket(this, publishPacket); _mqttClientSessionsManager.DispatchPublishPacket(this, publishPacket);
await Adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, new MqttPubAckPacket { PacketIdentifier = publishPacket.PacketIdentifier });
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, new MqttPubAckPacket { PacketIdentifier = publishPacket.PacketIdentifier });
return; return;
} }


@@ -205,21 +207,21 @@ namespace MQTTnet.Core.Server


_mqttClientSessionsManager.DispatchPublishPacket(this, publishPacket); _mqttClientSessionsManager.DispatchPublishPacket(this, publishPacket);


await Adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, new MqttPubRecPacket { PacketIdentifier = publishPacket.PacketIdentifier });
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, new MqttPubRecPacket { PacketIdentifier = publishPacket.PacketIdentifier });
return; return;
} }


throw new MqttCommunicationException("Received a not supported QoS level."); throw new MqttCommunicationException("Received a not supported QoS level.");
} }


private Task HandleIncomingPubRelPacketAsync(MqttPubRelPacket pubRelPacket)
private Task HandleIncomingPubRelPacketAsync(IMqttCommunicationAdapter adapter, MqttPubRelPacket pubRelPacket)
{ {
lock (_unacknowledgedPublishPackets) lock (_unacknowledgedPublishPackets)
{ {
_unacknowledgedPublishPackets.Remove(pubRelPacket.PacketIdentifier); _unacknowledgedPublishPackets.Remove(pubRelPacket.PacketIdentifier);
} }


return Adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, new MqttPubCompPacket { PacketIdentifier = pubRelPacket.PacketIdentifier });
return adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, new MqttPubCompPacket { PacketIdentifier = pubRelPacket.PacketIdentifier });
} }
} }
} }

+ 2
- 3
MQTTnet.Core/Server/MqttClientSessionsManager.cs View File

@@ -9,6 +9,7 @@ using MQTTnet.Core.Exceptions;
using MQTTnet.Core.Internal; using MQTTnet.Core.Internal;
using MQTTnet.Core.Packets; using MQTTnet.Core.Packets;
using MQTTnet.Core.Protocol; using MQTTnet.Core.Protocol;
using MQTTnet.Core.Serializer;


namespace MQTTnet.Core.Server namespace MQTTnet.Core.Server
{ {
@@ -24,9 +25,7 @@ namespace MQTTnet.Core.Server
} }


public event EventHandler<MqttApplicationMessageReceivedEventArgs> ApplicationMessageReceived; public event EventHandler<MqttApplicationMessageReceivedEventArgs> ApplicationMessageReceived;

public event EventHandler<MqttClientConnectedEventArgs> ClientConnected; public event EventHandler<MqttClientConnectedEventArgs> ClientConnected;

public event EventHandler<MqttClientDisconnectedEventArgs> ClientDisconnected; public event EventHandler<MqttClientDisconnectedEventArgs> ClientDisconnected;


public MqttClientRetainedMessagesManager RetainedMessagesManager { get; } public MqttClientRetainedMessagesManager RetainedMessagesManager { get; }
@@ -111,7 +110,7 @@ namespace MQTTnet.Core.Server
return _clientSessions.Where(s => s.Value.IsConnected).Select(s => new ConnectedMqttClient return _clientSessions.Where(s => s.Value.IsConnected).Select(s => new ConnectedMqttClient
{ {
ClientId = s.Value.ClientId, ClientId = s.Value.ClientId,
ProtocolVersion = s.Value.Adapter.PacketSerializer.ProtocolVersion
ProtocolVersion = s.Value.ProtocolVersion ?? MqttProtocolVersion.V311
}).ToList(); }).ToList();
} }
} }


+ 1
- 1
MQTTnet.sln View File

@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15 # Visual Studio 15
VisualStudioVersion = 15.0.26730.16 VisualStudioVersion = 15.0.26730.16
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MQTTnet.Core.Tests", "Tests\MQTTnet.Core.Tests\MQTTnet.Core.Tests.csproj", "{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Core.Tests", "Tests\MQTTnet.Core.Tests\MQTTnet.Core.Tests.csproj", "{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MQTTnet.NetFramework", "Frameworks\MQTTnet.NetFramework\MQTTnet.NetFramework.csproj", "{A480EF90-0EAA-4D9A-B271-47A9C47F6F7D}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MQTTnet.NetFramework", "Frameworks\MQTTnet.NetFramework\MQTTnet.NetFramework.csproj", "{A480EF90-0EAA-4D9A-B271-47A9C47F6F7D}"
EndProject EndProject


+ 1
- 1
README.md View File

@@ -18,7 +18,7 @@ MQTTnet is a .NET library for MQTT based communication. It provides a MQTT clien
* Performance optimized (processing ~27.000 messages / second)* * Performance optimized (processing ~27.000 messages / second)*
* Interfaces included for mocking and testing * Interfaces included for mocking and testing
* Access to internal trace messages * Access to internal trace messages
* Unit tested (57+ tests)
* Unit tested (58+ tests)


\* Tested on local machine with MQTTnet client and server running in the same process using the TCP channel. The app for verification is part of this repository and stored in _/Tests/MQTTnet.TestApp.NetFramework_. \* Tested on local machine with MQTTnet client and server running in the same process using the TCP channel. The app for verification is part of this repository and stored in _/Tests/MQTTnet.TestApp.NetFramework_.




+ 20
- 0
Tests/MQTTnet.Core.Tests/MqttCommunicationAdapterFactory.cs View File

@@ -0,0 +1,20 @@
using MQTTnet.Core.Adapter;
using MQTTnet.Core.Client;

namespace MQTTnet.Core.Tests
{
public class MqttCommunicationAdapterFactory : IMqttCommunicationAdapterFactory
{
private readonly IMqttCommunicationAdapter _adapter;

public MqttCommunicationAdapterFactory(IMqttCommunicationAdapter adapter)
{
_adapter = adapter;
}

public IMqttCommunicationAdapter CreateMqttCommunicationAdapter(MqttClientOptions options)
{
return _adapter;
}
}
}

+ 1
- 2
Tests/MQTTnet.Core.Tests/MqttPacketSerializerTests.cs View File

@@ -6,7 +6,6 @@ using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using MQTTnet.Core.Adapter; using MQTTnet.Core.Adapter;
using MQTTnet.Core.Channel; using MQTTnet.Core.Channel;
using MQTTnet.Core.Client;
using MQTTnet.Core.Packets; using MQTTnet.Core.Packets;
using MQTTnet.Core.Protocol; using MQTTnet.Core.Protocol;
using MQTTnet.Core.Serializer; using MQTTnet.Core.Serializer;
@@ -411,7 +410,7 @@ namespace MQTTnet.Core.Tests
_stream.Position = 0; _stream.Position = 0;
} }


public Task ConnectAsync(MqttClientOptions options)
public Task ConnectAsync()
{ {
return Task.FromResult(0); return Task.FromResult(0);
} }


+ 0
- 1
Tests/MQTTnet.Core.Tests/MqttServerTests.cs View File

@@ -6,7 +6,6 @@ using MQTTnet.Core.Client;
using MQTTnet.Core.Packets; using MQTTnet.Core.Packets;
using MQTTnet.Core.Protocol; using MQTTnet.Core.Protocol;
using MQTTnet.Core.Server; using MQTTnet.Core.Server;
using System;


namespace MQTTnet.Core.Tests namespace MQTTnet.Core.Tests
{ {


+ 1
- 2
Tests/MQTTnet.Core.Tests/TestMqttCommunicationAdapter.cs View File

@@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MQTTnet.Core.Adapter; using MQTTnet.Core.Adapter;
using MQTTnet.Core.Client;
using MQTTnet.Core.Packets; using MQTTnet.Core.Packets;
using MQTTnet.Core.Serializer; using MQTTnet.Core.Serializer;


@@ -18,7 +17,7 @@ namespace MQTTnet.Core.Tests


public IMqttPacketSerializer PacketSerializer { get; } = new MqttPacketSerializer(); public IMqttPacketSerializer PacketSerializer { get; } = new MqttPacketSerializer();


public Task ConnectAsync(TimeSpan timeout, MqttClientOptions options)
public Task ConnectAsync(TimeSpan timeout)
{ {
return Task.FromResult(0); return Task.FromResult(0);
} }


+ 7
- 7
Tests/MQTTnet.Core.Tests/TestMqttServerAdapter.cs View File

@@ -17,10 +17,11 @@ namespace MQTTnet.Core.Tests
adapterA.Partner = adapterB; adapterA.Partner = adapterB;
adapterB.Partner = adapterA; adapterB.Partner = adapterA;


var client = new MqttClient(new MqttClientOptions() { ClientId = clientId }, adapterA);
var client = new MqttClient(new MqttCommunicationAdapterFactory(adapterA));
var connected = WaitForClientToConnect(server, clientId); var connected = WaitForClientToConnect(server, clientId);

FireClientAcceptedEvent(adapterB); FireClientAcceptedEvent(adapterB);
await client.ConnectAsync(willMessage);
await client.ConnectAsync(new MqttClientTcpOptions { ClientId = clientId, WillMessage = willMessage });
await connected; await connected;


return client; return client;
@@ -30,17 +31,16 @@ namespace MQTTnet.Core.Tests
{ {
var tcs = new TaskCompletionSource<object>(); var tcs = new TaskCompletionSource<object>();


EventHandler<MqttClientConnectedEventArgs> handler = null;
handler = (sender, args) =>
void Handler(object sender, MqttClientConnectedEventArgs args)
{ {
if (args.Client.ClientId == clientId) if (args.Client.ClientId == clientId)
{ {
s.ClientConnected -= handler;
s.ClientConnected -= Handler;
tcs.SetResult(null); tcs.SetResult(null);
} }
};
}


s.ClientConnected += handler;
s.ClientConnected += Handler;


return tcs.Task; return tcs.Task;
} }


+ 5
- 6
Tests/MQTTnet.TestApp.NetCore/Program.cs View File

@@ -46,12 +46,11 @@ namespace MQTTnet.TestApp.NetCore


try try
{ {
var options = new MqttClientOptions
var options = new MqttClientWebSocketOptions
{ {
Server = "localhost",
Uri = "localhost",
ClientId = "XYZ", ClientId = "XYZ",
CleanSession = true,
ConnectionType = MqttConnectionType.Ws
CleanSession = true
}; };


var client = new MqttClientFactory().CreateMqttClient(options); var client = new MqttClientFactory().CreateMqttClient(options);
@@ -84,7 +83,7 @@ namespace MQTTnet.TestApp.NetCore


try try
{ {
await client.ConnectAsync();
await client.ConnectAsync(options);
} }
catch catch
{ {
@@ -94,7 +93,7 @@ namespace MQTTnet.TestApp.NetCore


try try
{ {
await client.ConnectAsync();
await client.ConnectAsync(options);
} }
catch (Exception exception) catch (Exception exception)
{ {


+ 3
- 3
Tests/MQTTnet.TestApp.NetFramework/PerformanceTest.cs View File

@@ -32,7 +32,7 @@ namespace MQTTnet.TestApp.NetFramework
{ {
try try
{ {
var options = new MqttClientOptions
var options = new MqttClientTcpOptions
{ {
Server = "localhost", Server = "localhost",
ClientId = "XYZ", ClientId = "XYZ",
@@ -64,7 +64,7 @@ namespace MQTTnet.TestApp.NetFramework


try try
{ {
await client.ConnectAsync();
await client.ConnectAsync(options);
} }
catch catch
{ {
@@ -74,7 +74,7 @@ namespace MQTTnet.TestApp.NetFramework


try try
{ {
await client.ConnectAsync();
await client.ConnectAsync(options);
} }
catch (Exception exception) catch (Exception exception)
{ {


+ 11
- 6
Tests/MQTTnet.TestApp.NetFramework/Program.cs View File

@@ -52,13 +52,18 @@ namespace MQTTnet.TestApp.NetFramework


try try
{ {
var options = new MqttClientOptions
var options = new MqttClientWebSocketOptions
{ {
Server = "localhost",
ClientId = "XYZ",
CleanSession = true
Uri = "broker.hivemq.com:8000/mqtt"
}; };


////var options = new MqttClientOptions
////{
//// Server = "localhost",
//// ClientId = "XYZ",
//// CleanSession = true
////};

var client = new MqttClientFactory().CreateMqttClient(options); var client = new MqttClientFactory().CreateMqttClient(options);
client.ApplicationMessageReceived += (s, e) => client.ApplicationMessageReceived += (s, e) =>
{ {
@@ -87,7 +92,7 @@ namespace MQTTnet.TestApp.NetFramework


try try
{ {
await client.ConnectAsync();
await client.ConnectAsync(options);
} }
catch catch
{ {
@@ -97,7 +102,7 @@ namespace MQTTnet.TestApp.NetFramework


try try
{ {
await client.ConnectAsync();
await client.ConnectAsync(options);
} }
catch (Exception exception) catch (Exception exception)
{ {


+ 27
- 10
Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs View File

@@ -37,15 +37,32 @@ namespace MQTTnet.TestApp.UniversalWindows


private async void Connect(object sender, RoutedEventArgs e) private async void Connect(object sender, RoutedEventArgs e)
{ {
var options = new MqttClientOptions
{
Server = Server.Text,
UserName = User.Text,
Password = Password.Text,
ClientId = ClientId.Text,
TlsOptions = { UseTls = UseTls.IsChecked == true },
ConnectionType = UseTcp.IsChecked == true ? MqttConnectionType.Tcp : MqttConnectionType.Ws
};
MqttClientOptions options = null;
if (UseTcp.IsChecked == true)
{
options = new MqttClientTcpOptions
{
Server = Server.Text
};
}

if (UseWs.IsChecked == true)
{
options = new MqttClientWebSocketOptions
{
Uri = Server.Text
};
}

if (options == null)
{
throw new InvalidOperationException();
}

options.UserName = User.Text;
options.Password = Password.Text;
options.ClientId = ClientId.Text;
options.TlsOptions.UseTls = UseTls.IsChecked == true;
try try
{ {
@@ -56,7 +73,7 @@ namespace MQTTnet.TestApp.UniversalWindows


var factory = new MqttClientFactory(); var factory = new MqttClientFactory();
_mqttClient = factory.CreateMqttClient(options); _mqttClient = factory.CreateMqttClient(options);
await _mqttClient.ConnectAsync();
await _mqttClient.ConnectAsync(options);
} }
catch (Exception exception) catch (Exception exception)
{ {


Loading…
Cancel
Save