Refactor options

This commit is contained in:
Christian Kratky
2017-10-04 13:58:51 +02:00
parent d23ab88add
commit 67267c05fd
40 changed files with 291 additions and 197 deletions
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet.Core.Client;
using MQTTnet.Core.Packets;
using MQTTnet.Core.Serializer;
@@ -12,7 +11,7 @@ namespace MQTTnet.Core.Adapter
{
IMqttPacketSerializer PacketSerializer { get; }
Task ConnectAsync(TimeSpan timeout, MqttClientOptions options);
Task ConnectAsync(TimeSpan timeout);
Task DisconnectAsync(TimeSpan timeout);
@@ -26,11 +26,11 @@ namespace MQTTnet.Core.Adapter
public IMqttPacketSerializer PacketSerializer { get; }
public async Task ConnectAsync(TimeSpan timeout, MqttClientOptions options)
public async Task ConnectAsync(TimeSpan timeout)
{
try
{
await _channel.ConnectAsync(options).TimeoutAfter(timeout).ConfigureAwait(false);
await _channel.ConnectAsync().TimeoutAfter(timeout).ConfigureAwait(false);
}
catch (TaskCanceledException)
{
@@ -1,5 +1,4 @@
using System.Threading.Tasks;
using MQTTnet.Core.Client;
using System.IO;
namespace MQTTnet.Core.Channel
@@ -10,7 +9,7 @@ namespace MQTTnet.Core.Channel
Stream ReceiveStream { get; }
Stream RawReceiveStream { get; }
Task ConnectAsync(MqttClientOptions options);
Task ConnectAsync();
Task DisconnectAsync();
}
}
+1 -1
View File
@@ -13,7 +13,7 @@ namespace MQTTnet.Core.Client
event EventHandler Connected;
event EventHandler Disconnected;
Task ConnectAsync(MqttApplicationMessage willApplicationMessage = null);
Task ConnectAsync(MqttClientOptions options);
Task DisconnectAsync();
Task<IList<MqttSubscribeResult>> SubscribeAsync(IEnumerable<TopicFilter> topicFilters);
@@ -0,0 +1,9 @@
using MQTTnet.Core.Adapter;
namespace MQTTnet.Core.Client
{
public interface IMqttCommunicationAdapterFactory
{
IMqttCommunicationAdapter CreateMqttCommunicationAdapter(MqttClientOptions options);
}
}
+13 -10
View File
@@ -16,19 +16,17 @@ namespace MQTTnet.Core.Client
{
private readonly HashSet<ushort> _unacknowledgedPublishPackets = new HashSet<ushort>();
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 int _latestPacketIdentifier;
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;
@@ -37,22 +35,27 @@ namespace MQTTnet.Core.Client
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.");
try
{
_options = options;
_cancellationTokenSource = new CancellationTokenSource();
_latestPacketIdentifier = 0;
_packetDispatcher.Reset();
_adapter = _communicationChannelFactory.CreateMqttCommunicationAdapter(options);
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.");
await SetupIncomingPacketProcessingAsync();
await AuthenticateAsync(willApplicationMessage);
await AuthenticateAsync(options.WillMessage);
MqttTrace.Verbose(nameof(MqttClient), "MQTT connection with server established.");
+3 -7
View File
@@ -3,14 +3,12 @@ using MQTTnet.Core.Serializer;
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 MqttApplicationMessage WillMessage { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
@@ -24,7 +22,5 @@ namespace MQTTnet.Core.Client
public TimeSpan DefaultCommunicationTimeout { get; set; } = TimeSpan.FromSeconds(10);
public MqttProtocolVersion ProtocolVersion { get; set; } = MqttProtocolVersion.V311;
public MqttConnectionType ConnectionType { get; set; } = MqttConnectionType.Tcp;
}
}
@@ -0,0 +1,9 @@
namespace MQTTnet.Core.Client
{
public class MqttClientTcpOptions : MqttClientOptions
{
public string Server { get; set; }
public int? Port { get; set; }
}
}
@@ -2,9 +2,9 @@
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));
@@ -0,0 +1,7 @@
namespace MQTTnet.Core.Client
{
public class MqttClientWebSocketOptions : MqttClientOptions
{
public string Uri { get; set; }
}
}
@@ -1,8 +0,0 @@
namespace MQTTnet.Core.Client
{
public enum MqttConnectionType
{
Tcp,
Ws
}
}
@@ -72,6 +72,9 @@ namespace MQTTnet.Core.Server
{
MqttTrace.Warning(nameof(MqttClientPendingMessagesQueue), exception, "Sending publish packet failed due to communication exception.");
}
if (exception is OperationCanceledException)
{
}
else
{
MqttTrace.Error(nameof(MqttClientPendingMessagesQueue), exception, "Sending publish packet failed.");
+20 -18
View File
@@ -8,6 +8,7 @@ using MQTTnet.Core.Exceptions;
using MQTTnet.Core.Internal;
using MQTTnet.Core.Packets;
using MQTTnet.Core.Protocol;
using MQTTnet.Core.Serializer;
namespace MQTTnet.Core.Server
{
@@ -19,7 +20,8 @@ namespace MQTTnet.Core.Server
private readonly MqttClientSessionsManager _mqttClientSessionsManager;
private readonly MqttClientPendingMessagesQueue _pendingMessagesQueue;
private readonly MqttServerOptions _options;
private IMqttCommunicationAdapter _adapter;
private CancellationTokenSource _cancellationTokenSource;
private MqttApplicationMessage _willMessage;
@@ -33,9 +35,9 @@ namespace MQTTnet.Core.Server
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)
{
@@ -45,7 +47,7 @@ namespace MQTTnet.Core.Server
try
{
Adapter = adapter;
_adapter = adapter;
_cancellationTokenSource = new CancellationTokenSource();
_pendingMessagesQueue.Start(adapter, _cancellationTokenSource.Token);
@@ -75,7 +77,7 @@ namespace MQTTnet.Core.Server
_cancellationTokenSource?.Dispose();
_cancellationTokenSource = null;
Adapter = null;
_adapter = null;
MqttTrace.Information(nameof(MqttClientSession), "Client '{0}': Disconnected.", ClientId);
}
@@ -106,7 +108,7 @@ namespace MQTTnet.Core.Server
while (!cancellationToken.IsCancellationRequested)
{
var packet = await adapter.ReceivePacketAsync(TimeSpan.Zero, cancellationToken).ConfigureAwait(false);
await ProcessReceivedPacketAsync(packet).ConfigureAwait(false);
await ProcessReceivedPacketAsync(adapter, packet).ConfigureAwait(false);
}
}
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)
{
await Adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, _subscriptionsManager.Subscribe(subscribePacket));
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, _cancellationTokenSource.Token, _subscriptionsManager.Subscribe(subscribePacket));
EnqueueRetainedMessages(subscribePacket);
}
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)
{
await HandleIncomingPublishPacketAsync(publishPacket);
await HandleIncomingPublishPacketAsync(adapter, publishPacket);
}
else if (packet is MqttPubRelPacket pubRelPacket)
{
await HandleIncomingPubRelPacketAsync(pubRelPacket);
await HandleIncomingPubRelPacketAsync(adapter, pubRelPacket);
}
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)
{
@@ -153,7 +155,7 @@ namespace MQTTnet.Core.Server
}
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)
{
@@ -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)
{
@@ -191,7 +193,7 @@ namespace MQTTnet.Core.Server
if (publishPacket.QualityOfServiceLevel == MqttQualityOfServiceLevel.AtLeastOnce)
{
_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;
}
@@ -205,21 +207,21 @@ namespace MQTTnet.Core.Server
_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;
}
throw new MqttCommunicationException("Received a not supported QoS level.");
}
private Task HandleIncomingPubRelPacketAsync(MqttPubRelPacket pubRelPacket)
private Task HandleIncomingPubRelPacketAsync(IMqttCommunicationAdapter adapter, MqttPubRelPacket pubRelPacket)
{
lock (_unacknowledgedPublishPackets)
{
_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 });
}
}
}
@@ -9,6 +9,7 @@ using MQTTnet.Core.Exceptions;
using MQTTnet.Core.Internal;
using MQTTnet.Core.Packets;
using MQTTnet.Core.Protocol;
using MQTTnet.Core.Serializer;
namespace MQTTnet.Core.Server
{
@@ -24,9 +25,7 @@ namespace MQTTnet.Core.Server
}
public event EventHandler<MqttApplicationMessageReceivedEventArgs> ApplicationMessageReceived;
public event EventHandler<MqttClientConnectedEventArgs> ClientConnected;
public event EventHandler<MqttClientDisconnectedEventArgs> ClientDisconnected;
public MqttClientRetainedMessagesManager RetainedMessagesManager { get; }
@@ -111,7 +110,7 @@ namespace MQTTnet.Core.Server
return _clientSessions.Where(s => s.Value.IsConnected).Select(s => new ConnectedMqttClient
{
ClientId = s.Value.ClientId,
ProtocolVersion = s.Value.Adapter.PacketSerializer.ProtocolVersion
ProtocolVersion = s.Value.ProtocolVersion ?? MqttProtocolVersion.V311
}).ToList();
}
}