Refactoring

This commit is contained in:
Christian Kratky
2017-10-19 18:50:22 +02:00
parent 9915cc4492
commit 40b1be075c
31 changed files with 166 additions and 137 deletions
@@ -7,7 +7,7 @@ namespace MQTTnet.Implementations
{ {
public class MqttCommunicationAdapterFactory : IMqttCommunicationAdapterFactory public class MqttCommunicationAdapterFactory : IMqttCommunicationAdapterFactory
{ {
public IMqttCommunicationAdapter CreateMqttCommunicationAdapter(MqttClientOptions options) public IMqttCommunicationAdapter CreateMqttCommunicationAdapter(IMqttClientOptions options)
{ {
if (options == null) throw new ArgumentNullException(nameof(options)); if (options == null) throw new ArgumentNullException(nameof(options));
@@ -48,8 +48,7 @@ namespace MQTTnet.Implementations
public Stream SendStream { get; private set; } public Stream SendStream { get; private set; }
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 static Func<X509Certificate, X509Chain, SslPolicyErrors, MqttClientTcpOptions, bool> CustomCertificateValidationCallback { get; set; } public static Func<X509Certificate, X509Chain, SslPolicyErrors, MqttClientTcpOptions, bool> CustomCertificateValidationCallback { get; set; }
public async Task ConnectAsync() public async Task ConnectAsync()
@@ -121,7 +120,7 @@ namespace MQTTnet.Implementations
return _options.TlsOptions.AllowUntrustedCertificates; return _options.TlsOptions.AllowUntrustedCertificates;
} }
private static X509CertificateCollection LoadCertificates(MqttClientOptions options) private static X509CertificateCollection LoadCertificates(IMqttClientOptions options)
{ {
var certificates = new X509CertificateCollection(); var certificates = new X509CertificateCollection();
if (options.TlsOptions.Certificates == null) if (options.TlsOptions.Certificates == null)
@@ -7,7 +7,7 @@ namespace MQTTnet.Implementations
{ {
public class MqttCommunicationAdapterFactory : IMqttCommunicationAdapterFactory public class MqttCommunicationAdapterFactory : IMqttCommunicationAdapterFactory
{ {
public IMqttCommunicationAdapter CreateMqttCommunicationAdapter(MqttClientOptions options) public IMqttCommunicationAdapter CreateMqttCommunicationAdapter(IMqttClientOptions options)
{ {
if (options == null) throw new ArgumentNullException(nameof(options)); if (options == null) throw new ArgumentNullException(nameof(options));
@@ -89,7 +89,7 @@ namespace MQTTnet.Implementations
RawReceiveStream = ReceiveStream; RawReceiveStream = ReceiveStream;
} }
private static Certificate LoadCertificate(MqttClientOptions options) private static Certificate LoadCertificate(BaseMqttClientOptions options)
{ {
if (options.TlsOptions.Certificates == null || !options.TlsOptions.Certificates.Any()) if (options.TlsOptions.Certificates == null || !options.TlsOptions.Certificates.Any())
{ {
@@ -3,7 +3,7 @@ using MQTTnet.Core.Serializer;
namespace MQTTnet.Core.Client namespace MQTTnet.Core.Client
{ {
public abstract class MqttClientOptions public abstract class BaseMqttClientOptions : IMqttClientOptions
{ {
public MqttClientTlsOptions TlsOptions { get; set; } = new MqttClientTlsOptions(); public MqttClientTlsOptions TlsOptions { get; set; } = new MqttClientTlsOptions();
@@ -13,7 +13,7 @@ namespace MQTTnet.Core.Client
public string Password { get; set; } public string Password { get; set; }
public string ClientId { get; set; } = Guid.NewGuid().ToString().Replace("-", string.Empty); public string ClientId { get; set; } = Guid.NewGuid().ToString("N");
public bool CleanSession { get; set; } = true; public bool CleanSession { get; set; } = true;
+2 -2
View File
@@ -11,9 +11,9 @@ namespace MQTTnet.Core.Client
event EventHandler<MqttApplicationMessageReceivedEventArgs> ApplicationMessageReceived; event EventHandler<MqttApplicationMessageReceivedEventArgs> ApplicationMessageReceived;
event EventHandler Connected; event EventHandler Connected;
event EventHandler Disconnected; event EventHandler<MqttClientDisconnectedEventArgs> Disconnected;
Task ConnectAsync(MqttClientOptions options); Task ConnectAsync(IMqttClientOptions options);
Task DisconnectAsync(); Task DisconnectAsync();
Task<IList<MqttSubscribeResult>> SubscribeAsync(IEnumerable<TopicFilter> topicFilters); Task<IList<MqttSubscribeResult>> SubscribeAsync(IEnumerable<TopicFilter> topicFilters);
+18
View File
@@ -0,0 +1,18 @@
using System;
using MQTTnet.Core.Serializer;
namespace MQTTnet.Core.Client
{
public interface IMqttClientOptions
{
bool CleanSession { get; }
string ClientId { get; }
TimeSpan DefaultCommunicationTimeout { get; }
TimeSpan KeepAlivePeriod { get; }
string Password { get; }
MqttProtocolVersion ProtocolVersion { get; }
MqttClientTlsOptions TlsOptions { get; }
string UserName { get; }
MqttApplicationMessage WillMessage { get; }
}
}
@@ -4,6 +4,6 @@ namespace MQTTnet.Core.Client
{ {
public interface IMqttCommunicationAdapterFactory public interface IMqttCommunicationAdapterFactory
{ {
IMqttCommunicationAdapter CreateMqttCommunicationAdapter(MqttClientOptions options); IMqttCommunicationAdapter CreateMqttCommunicationAdapter(IMqttClientOptions options);
} }
} }
+9 -5
View File
@@ -18,7 +18,7 @@ namespace MQTTnet.Core.Client
private readonly MqttPacketDispatcher _packetDispatcher = new MqttPacketDispatcher(); private readonly MqttPacketDispatcher _packetDispatcher = new MqttPacketDispatcher();
private readonly IMqttCommunicationAdapterFactory _communicationChannelFactory; private readonly IMqttCommunicationAdapterFactory _communicationChannelFactory;
private MqttClientOptions _options; private IMqttClientOptions _options;
private bool _isReceivingPackets; private bool _isReceivingPackets;
private int _latestPacketIdentifier; private int _latestPacketIdentifier;
private CancellationTokenSource _cancellationTokenSource; private CancellationTokenSource _cancellationTokenSource;
@@ -30,12 +30,12 @@ namespace MQTTnet.Core.Client
} }
public event EventHandler Connected; public event EventHandler Connected;
public event EventHandler Disconnected; public event EventHandler<MqttClientDisconnectedEventArgs> Disconnected;
public event EventHandler<MqttApplicationMessageReceivedEventArgs> ApplicationMessageReceived; public event EventHandler<MqttApplicationMessageReceivedEventArgs> ApplicationMessageReceived;
public bool IsConnected => _cancellationTokenSource != null && !_cancellationTokenSource.IsCancellationRequested; public bool IsConnected { get; private set; }
public async Task ConnectAsync(MqttClientOptions options) public async Task ConnectAsync(IMqttClientOptions options)
{ {
if (options == null) throw new ArgumentNullException(nameof(options)); if (options == null) throw new ArgumentNullException(nameof(options));
@@ -64,6 +64,7 @@ namespace MQTTnet.Core.Client
StartSendKeepAliveMessages(_cancellationTokenSource.Token); StartSendKeepAliveMessages(_cancellationTokenSource.Token);
} }
IsConnected = true;
Connected?.Invoke(this, EventArgs.Empty); Connected?.Invoke(this, EventArgs.Empty);
} }
catch (Exception) catch (Exception)
@@ -222,6 +223,9 @@ namespace MQTTnet.Core.Client
private async Task DisconnectInternalAsync() private async Task DisconnectInternalAsync()
{ {
var clientWasConnected = IsConnected;
IsConnected = false;
var cts = _cancellationTokenSource; var cts = _cancellationTokenSource;
if (cts == null || cts.IsCancellationRequested) if (cts == null || cts.IsCancellationRequested)
{ {
@@ -243,7 +247,7 @@ namespace MQTTnet.Core.Client
} }
finally finally
{ {
Disconnected?.Invoke(this, EventArgs.Empty); Disconnected?.Invoke(this, new MqttClientDisconnectedEventArgs(clientWasConnected));
} }
} }
@@ -0,0 +1,14 @@
using System;
namespace MQTTnet.Core.Client
{
public class MqttClientDisconnectedEventArgs : EventArgs
{
public MqttClientDisconnectedEventArgs(bool clientWasConnected)
{
ClientWasConnected = clientWasConnected;
}
public bool ClientWasConnected { get; }
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
namespace MQTTnet.Core.Client namespace MQTTnet.Core.Client
{ {
public class MqttClientTcpOptions : MqttClientOptions public class MqttClientTcpOptions : BaseMqttClientOptions
{ {
public string Server { get; set; } public string Server { get; set; }
@@ -1,6 +1,6 @@
namespace MQTTnet.Core.Client namespace MQTTnet.Core.Client
{ {
public class MqttClientWebSocketOptions : MqttClientOptions public class MqttClientWebSocketOptions : BaseMqttClientOptions
{ {
public string Uri { get; set; } public string Uri { get; set; }
} }
@@ -17,10 +17,5 @@ namespace MQTTnet.Core.Exceptions
: base(message) : base(message)
{ {
} }
public MqttCommunicationException(string message, Exception innerException)
: base(message, innerException)
{
}
} }
} }
+4
View File
@@ -32,4 +32,8 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Any CPU|x86'" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Any CPU|x86'" />
<ItemGroup>
<Folder Include="ManagedClient\" />
</ItemGroup>
</Project> </Project>
@@ -8,13 +8,6 @@ namespace MQTTnet.Core
{ {
public class MqttApplicationMessageFactory public class MqttApplicationMessageFactory
{ {
public MqttApplicationMessage CreateApplicationMessage(string topic, MqttQualityOfServiceLevel qualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce, bool retain = false)
{
if (topic == null) throw new ArgumentNullException(nameof(topic));
return CreateApplicationMessage(topic, new byte[0], qualityOfServiceLevel, retain);
}
public MqttApplicationMessage CreateApplicationMessage(string topic, byte[] payload, MqttQualityOfServiceLevel qualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce, bool retain = false) public MqttApplicationMessage CreateApplicationMessage(string topic, byte[] payload, MqttQualityOfServiceLevel qualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce, bool retain = false)
{ {
if (topic == null) throw new ArgumentNullException(nameof(topic)); if (topic == null) throw new ArgumentNullException(nameof(topic));
+1 -2
View File
@@ -12,8 +12,7 @@ namespace MQTTnet.Core.Packets
if (responsePacket is IMqttPacketWithIdentifier responsePacketWithIdentifier) if (responsePacket is IMqttPacketWithIdentifier responsePacketWithIdentifier)
{ {
var requestPacketWithIdentifier = packet as IMqttPacketWithIdentifier; if (!(packet is IMqttPacketWithIdentifier requestPacketWithIdentifier))
if (requestPacketWithIdentifier == null)
{ {
throw new InvalidOperationException("Response packet has PacketIdentifier but request packet does not."); throw new InvalidOperationException("Response packet has PacketIdentifier but request packet does not.");
} }
+1 -1
View File
@@ -8,7 +8,7 @@ namespace MQTTnet.Core.Packets
{ {
public ushort PacketIdentifier { get; set; } public ushort PacketIdentifier { get; set; }
public IList<MqttSubscribeReturnCode> SubscribeReturnCodes { get; set; } = new List<MqttSubscribeReturnCode>(); public IList<MqttSubscribeReturnCode> SubscribeReturnCodes { get; } = new List<MqttSubscribeReturnCode>();
public override string ToString() public override string ToString()
{ {
+10 -21
View File
@@ -58,19 +58,19 @@ namespace MQTTnet.Core.Serializer
return Serialize(connAckPacket, writer); return Serialize(connAckPacket, writer);
} }
if (packet is MqttDisconnectPacket disconnectPacket) if (packet is MqttDisconnectPacket)
{ {
return Serialize(disconnectPacket); return SerializeEmptyPacket(MqttControlPacketType.Disconnect);
} }
if (packet is MqttPingReqPacket pingReqPacket) if (packet is MqttPingReqPacket)
{ {
return Serialize(pingReqPacket); return SerializeEmptyPacket(MqttControlPacketType.PingReq);
} }
if (packet is MqttPingRespPacket pingRespPacket) if (packet is MqttPingRespPacket)
{ {
return Serialize(pingRespPacket); return SerializeEmptyPacket(MqttControlPacketType.PingResp);
} }
if (packet is MqttPublishPacket publishPacket) if (packet is MqttPublishPacket publishPacket)
@@ -338,6 +338,8 @@ namespace MQTTnet.Core.Serializer
private static void ValidateConnectPacket(MqttConnectPacket packet) private static void ValidateConnectPacket(MqttConnectPacket packet)
{ {
if (packet == null) throw new ArgumentNullException(nameof(packet));
if (string.IsNullOrEmpty(packet.ClientId) && !packet.CleanSession) if (string.IsNullOrEmpty(packet.ClientId) && !packet.CleanSession)
{ {
throw new MqttProtocolViolationException("CleanSession must be set if ClientId is empty [MQTT-3.1.3-7]."); throw new MqttProtocolViolationException("CleanSession must be set if ClientId is empty [MQTT-3.1.3-7].");
@@ -346,6 +348,8 @@ namespace MQTTnet.Core.Serializer
private static void ValidatePublishPacket(MqttPublishPacket packet) private static void ValidatePublishPacket(MqttPublishPacket packet)
{ {
if (packet == null) throw new ArgumentNullException(nameof(packet));
if (packet.QualityOfServiceLevel == 0 && packet.Dup) if (packet.QualityOfServiceLevel == 0 && packet.Dup)
{ {
throw new MqttProtocolViolationException("Dup flag must be false for QoS 0 packets [MQTT-3.3.1-2]."); throw new MqttProtocolViolationException("Dup flag must be false for QoS 0 packets [MQTT-3.3.1-2].");
@@ -433,21 +437,6 @@ namespace MQTTnet.Core.Serializer
return MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.PubRel, 0x02); return MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.PubRel, 0x02);
} }
private static byte Serialize(MqttDisconnectPacket packet)
{
return SerializeEmptyPacket(MqttControlPacketType.Disconnect);
}
private static byte Serialize(MqttPingReqPacket packet)
{
return SerializeEmptyPacket(MqttControlPacketType.PingReq);
}
private static byte Serialize(MqttPingRespPacket packet)
{
return SerializeEmptyPacket(MqttControlPacketType.PingResp);
}
private static byte Serialize(MqttPublishPacket packet, MqttPacketWriter writer) private static byte Serialize(MqttPublishPacket packet, MqttPacketWriter writer)
{ {
ValidatePublishPacket(packet); ValidatePublishPacket(packet);
+1 -2
View File
@@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using MQTTnet.Core.Adapter;
namespace MQTTnet.Core.Server namespace MQTTnet.Core.Server
{ {
@@ -11,7 +10,7 @@ namespace MQTTnet.Core.Server
event EventHandler<MqttClientConnectedEventArgs> ClientConnected; event EventHandler<MqttClientConnectedEventArgs> ClientConnected;
event EventHandler<MqttClientDisconnectedEventArgs> ClientDisconnected; event EventHandler<MqttClientDisconnectedEventArgs> ClientDisconnected;
IReadOnlyList<ConnectedMqttClient> GetConnectedClients(); IList<ConnectedMqttClient> GetConnectedClients();
void Publish(MqttApplicationMessage applicationMessage); void Publish(MqttApplicationMessage applicationMessage);
Task StartAsync(); Task StartAsync();
@@ -103,7 +103,7 @@ namespace MQTTnet.Core.Server
} }
} }
public IReadOnlyList<ConnectedMqttClient> GetConnectedClients() public IList<ConnectedMqttClient> GetConnectedClients()
{ {
lock (_clientSessions) lock (_clientSessions)
{ {
+1 -1
View File
@@ -27,7 +27,7 @@ namespace MQTTnet.Core.Server
_clientSessionsManager.ClientDisconnected += OnClientDisconnected; _clientSessionsManager.ClientDisconnected += OnClientDisconnected;
} }
public IReadOnlyList<ConnectedMqttClient> GetConnectedClients() public IList<ConnectedMqttClient> GetConnectedClients()
{ {
return _clientSessionsManager.GetConnectedClients(); return _clientSessionsManager.GetConnectedClients();
} }
+1 -1
View File
@@ -55,7 +55,7 @@ namespace MQTTnet.Core.Tests
{ {
try try
{ {
var r = await Task.Run(() => await Task.Run(() =>
{ {
var iis = new int[0]; var iis = new int[0];
return iis[1]; return iis[1];
@@ -0,0 +1,30 @@
using System;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MQTTnet.Core.Protocol;
namespace MQTTnet.Core.Tests
{
[TestClass]
public class MqttApplicationMessageFactoryTests
{
[TestMethod]
public void CreateApplicationMessage_TopicOnly()
{
var message = new MqttApplicationMessageFactory().CreateApplicationMessage("Abc", MqttQualityOfServiceLevel.AtLeastOnce);
Assert.AreEqual("Abc", message.Topic);
Assert.IsFalse(message.Retain);
Assert.AreEqual(MqttQualityOfServiceLevel.AtLeastOnce, message.QualityOfServiceLevel);
}
[TestMethod]
public void CreateApplicationMessage_TimeStampPayload()
{
var message = new MqttApplicationMessageFactory().CreateApplicationMessage("xyz", TimeSpan.FromSeconds(360));
Assert.AreEqual("xyz", message.Topic);
Assert.IsFalse(message.Retain);
Assert.AreEqual(MqttQualityOfServiceLevel.AtMostOnce, message.QualityOfServiceLevel);
Assert.AreEqual(Encoding.UTF8.GetString(message.Payload), "00:06:00");
}
}
}
@@ -12,7 +12,7 @@ namespace MQTTnet.Core.Tests
_adapter = adapter; _adapter = adapter;
} }
public IMqttCommunicationAdapter CreateMqttCommunicationAdapter(MqttClientOptions options) public IMqttCommunicationAdapter CreateMqttCommunicationAdapter(IMqttClientOptions options)
{ {
return _adapter; return _adapter;
} }
@@ -2,10 +2,8 @@
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
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.Packets; using MQTTnet.Core.Packets;
using MQTTnet.Core.Protocol; using MQTTnet.Core.Protocol;
using MQTTnet.Core.Serializer; using MQTTnet.Core.Serializer;
@@ -387,45 +385,6 @@ namespace MQTTnet.Core.Tests
DeserializeAndCompare(p, "sAIAew=="); DeserializeAndCompare(p, "sAIAew==");
} }
public class TestChannel : IMqttCommunicationChannel
{
private readonly MemoryStream _stream = new MemoryStream();
public Stream ReceiveStream => _stream;
public Stream RawReceiveStream => _stream;
public Stream SendStream => _stream;
public bool IsConnected { get; } = true;
public TestChannel()
{
}
public TestChannel(byte[] initialData)
{
_stream.Write(initialData, 0, initialData.Length);
_stream.Position = 0;
}
public Task ConnectAsync()
{
return Task.FromResult(0);
}
public Task DisconnectAsync()
{
return Task.FromResult(0);
}
public byte[] ToArray()
{
return _stream.ToArray();
}
}
private static void SerializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311) private static void SerializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
{ {
var serializer = new MqttPacketSerializer { ProtocolVersion = protocolVersion }; var serializer = new MqttPacketSerializer { ProtocolVersion = protocolVersion };
@@ -6,6 +6,10 @@
<TargetFrameworks>netcoreapp2.0;net45</TargetFrameworks> <TargetFrameworks>netcoreapp2.0;net45</TargetFrameworks>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\Frameworks\MQTTnet.Netstandard\MQTTnet.NetStandard.csproj" /> <ProjectReference Include="..\..\Frameworks\MQTTnet.Netstandard\MQTTnet.NetStandard.csproj" />
<ProjectReference Include="..\..\MQTTnet.Core\MQTTnet.Core.csproj" /> <ProjectReference Include="..\..\MQTTnet.Core\MQTTnet.Core.csproj" />
@@ -113,7 +113,8 @@ namespace MQTTnet.TestApp.NetCore
.Select(i => CreateMessage()) .Select(i => CreateMessage())
.ToList(); .ToList();
if (true) Console.WriteLine("Press 'c' for concurrent sends. Otherwise in one batch.");
if (Console.ReadKey().KeyChar == 'c')
{ {
//send concurrent (test for raceconditions) //send concurrent (test for raceconditions)
var sendTasks = msgs var sendTasks = msgs
@@ -161,10 +162,7 @@ namespace MQTTnet.TestApp.NetCore
private static Task PublishSingleMessage(IMqttClient client, MqttApplicationMessage applicationMessage, ref int count) private static Task PublishSingleMessage(IMqttClient client, MqttApplicationMessage applicationMessage, ref int count)
{ {
Interlocked.Increment(ref count); Interlocked.Increment(ref count);
return Task.Run(() => return Task.Run(() => client.PublishAsync(applicationMessage));
{
return client.PublishAsync(applicationMessage);
});
} }
private static async Task RunServerAsync() private static async Task RunServerAsync()
+46 -5
View File
@@ -6,16 +6,18 @@ using MQTTnet.Core.Protocol;
using MQTTnet.Core.Server; using MQTTnet.Core.Server;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json;
namespace MQTTnet.TestApp.NetCore namespace MQTTnet.TestApp.NetCore
{ {
public static class Program public static class Program
{ {
public static void Main(string[] args) public static void Main()
{ {
Console.WriteLine("MQTTnet - TestApp.NetFramework"); Console.WriteLine("MQTTnet - TestApp.NetFramework");
Console.WriteLine("1 = Start client"); Console.WriteLine("1 = Start client");
@@ -24,12 +26,12 @@ namespace MQTTnet.TestApp.NetCore
var pressedKey = Console.ReadKey(true); var pressedKey = Console.ReadKey(true);
if (pressedKey.Key == ConsoleKey.D1) if (pressedKey.Key == ConsoleKey.D1)
{ {
Task.Run(() => RunClientAsync(args)); Task.Run(RunClientAsync);
Thread.Sleep(Timeout.Infinite); Thread.Sleep(Timeout.Infinite);
} }
else if (pressedKey.Key == ConsoleKey.D2) else if (pressedKey.Key == ConsoleKey.D2)
{ {
Task.Run(() => RunServerAsync(args)); Task.Run(() => RunServerAsync());
Thread.Sleep(Timeout.Infinite); Thread.Sleep(Timeout.Infinite);
} }
else if (pressedKey.Key == ConsoleKey.D3) else if (pressedKey.Key == ConsoleKey.D3)
@@ -39,7 +41,7 @@ namespace MQTTnet.TestApp.NetCore
} }
} }
private static async Task RunClientAsync(string[] arguments) private static async Task RunClientAsync()
{ {
MqttNetTrace.TraceMessagePublished += (s, e) => MqttNetTrace.TraceMessagePublished += (s, e) =>
{ {
@@ -128,7 +130,7 @@ namespace MQTTnet.TestApp.NetCore
} }
} }
private static void RunServerAsync(string[] arguments) private static Task RunServerAsync()
{ {
MqttNetTrace.TraceMessagePublished += (s, e) => MqttNetTrace.TraceMessagePublished += (s, e) =>
{ {
@@ -157,10 +159,21 @@ namespace MQTTnet.TestApp.NetCore
} }
}; };
options.Storage = new RetainedMessageHandler();
var certificate = new X509Certificate(@"C:\certs\test\test.cer", ""); var certificate = new X509Certificate(@"C:\certs\test\test.cer", "");
options.TlsEndpointOptions.Certificate = certificate.Export(X509ContentType.Cert); options.TlsEndpointOptions.Certificate = certificate.Export(X509ContentType.Cert);
options.ConnectionBacklog = 5;
options.DefaultEndpointOptions.IsEnabled = true;
options.TlsEndpointOptions.IsEnabled = false;
var mqttServer = new MqttServerFactory().CreateMqttServer(options); var mqttServer = new MqttServerFactory().CreateMqttServer(options);
mqttServer.ClientDisconnected += (s, e) =>
{
Console.Write("Client disconnected event fired.");
};
mqttServer.StartAsync(); mqttServer.StartAsync();
Console.WriteLine("Press any key to exit."); Console.WriteLine("Press any key to exit.");
@@ -174,6 +187,34 @@ namespace MQTTnet.TestApp.NetCore
} }
Console.ReadLine(); Console.ReadLine();
return Task.FromResult(0);
}
}
public class RetainedMessageHandler : IMqttServerStorage
{
private const string Filename = "C:\\MQTT\\RetainedMessages.json";
public Task SaveRetainedMessagesAsync(IList<MqttApplicationMessage> messages)
{
File.WriteAllText(Filename, JsonConvert.SerializeObject(messages));
return Task.FromResult(0);
}
public Task<IList<MqttApplicationMessage>> LoadRetainedMessagesAsync()
{
IList<MqttApplicationMessage> retainedMessages;
if (File.Exists(Filename))
{
var json = File.ReadAllText(Filename);
retainedMessages = JsonConvert.DeserializeObject<List<MqttApplicationMessage>>(json);
}
else
{
retainedMessages = new List<MqttApplicationMessage>();
}
return Task.FromResult(retainedMessages);
} }
} }
} }
@@ -1,35 +1,18 @@
using System; using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel; using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation; using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation; using Windows.UI.Xaml.Navigation;
namespace MQTTnet.TestApp.UniversalWindows namespace MQTTnet.TestApp.UniversalWindows
{ {
/// <summary> sealed partial class App
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
sealed partial class App : Application
{ {
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App() public App()
{ {
this.InitializeComponent(); InitializeComponent();
this.Suspending += OnSuspending; Suspending += OnSuspending;
} }
/// <summary> /// <summary>
@@ -39,11 +22,9 @@ namespace MQTTnet.TestApp.UniversalWindows
/// <param name="e">Details about the launch request and process.</param> /// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e) protected override void OnLaunched(LaunchActivatedEventArgs e)
{ {
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content, // Do not repeat app initialization when the Window already has content,
// just ensure that the window is active // just ensure that the window is active
if (rootFrame == null) if (!(Window.Current.Content is Frame rootFrame))
{ {
// Create a Frame to act as the navigation context and navigate to the first page // Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame(); rootFrame = new Frame();
@@ -58,7 +58,7 @@
<TextBlock>QoS:</TextBlock> <TextBlock>QoS:</TextBlock>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<RadioButton Margin="0,0,10,0" x:Name="QoS0" IsChecked="True" GroupName="qos">0 (At most once)</RadioButton> <RadioButton Margin="0,0,10,0" IsChecked="True" GroupName="qos">0 (At most once)</RadioButton>
<RadioButton Margin="0,0,10,0" x:Name="QoS1" GroupName="qos">1 (At least once)</RadioButton> <RadioButton Margin="0,0,10,0" x:Name="QoS1" GroupName="qos">1 (At least once)</RadioButton>
<RadioButton Margin="0,0,10,0" x:Name="QoS2" GroupName="qos">2 (Exactly once)</RadioButton> <RadioButton Margin="0,0,10,0" x:Name="QoS2" GroupName="qos">2 (Exactly once)</RadioButton>
</StackPanel> </StackPanel>
@@ -73,7 +73,7 @@
<TextBlock>QoS:</TextBlock> <TextBlock>QoS:</TextBlock>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<RadioButton Margin="0,0,10,0" x:Name="SubscribeQoS0" IsChecked="True" GroupName="sqos">0 (At most once)</RadioButton> <RadioButton Margin="0,0,10,0" IsChecked="True" GroupName="sqos">0 (At most once)</RadioButton>
<RadioButton Margin="0,0,10,0" x:Name="SubscribeQoS1" GroupName="sqos">1 (At least once)</RadioButton> <RadioButton Margin="0,0,10,0" x:Name="SubscribeQoS1" GroupName="sqos">1 (At least once)</RadioButton>
<RadioButton Margin="0,0,10,0" x:Name="SubscribeQoS2" GroupName="sqos">2 (Exactly once)</RadioButton> <RadioButton Margin="0,0,10,0" x:Name="SubscribeQoS2" GroupName="sqos">2 (Exactly once)</RadioButton>
</StackPanel> </StackPanel>
@@ -41,7 +41,7 @@ namespace MQTTnet.TestApp.UniversalWindows
private async void Connect(object sender, RoutedEventArgs e) private async void Connect(object sender, RoutedEventArgs e)
{ {
MqttClientOptions options = null; BaseMqttClientOptions options = null;
if (UseTcp.IsChecked == true) if (UseTcp.IsChecked == true)
{ {
options = new MqttClientTcpOptions options = new MqttClientTcpOptions
@@ -195,6 +195,8 @@ namespace MQTTnet.TestApp.UniversalWindows
} }
} }
// This code is for the Wiki at GitHub!
// ReSharper disable once UnusedMember.Local
private async Task WikiCode() private async Task WikiCode()
{ {
var mqttClient = new MqttClientFactory().CreateMqttClient(); var mqttClient = new MqttClientFactory().CreateMqttClient();