mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-11-01 19:54:07 +08:00
Refactoring
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
+1
-1
@@ -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())
|
||||||
{
|
{
|
||||||
|
|||||||
+2
-2
@@ -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;
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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,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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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,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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user