improved client livetime events

This commit is contained in:
JanEggers
2017-10-02 22:55:46 +02:00
parent c7b7d56229
commit 3079ad37ce
10 changed files with 71 additions and 53 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ namespace MQTTnet.Core.Server
event EventHandler<MqttClientDisconnectedEventArgs> ClientDisconnected;
IList<ConnectedMqttClient> GetConnectedClients();
void InjectClient(string identifier, IMqttCommunicationAdapter adapter);
void InjectClient(IMqttCommunicationAdapter adapter);
void Publish(MqttApplicationMessage applicationMessage);
Task StartAsync();
+10 -12
View File
@@ -19,8 +19,7 @@ namespace MQTTnet.Core.Server
private readonly MqttClientSessionsManager _mqttClientSessionsManager;
private readonly MqttClientPendingMessagesQueue _pendingMessagesQueue;
private readonly MqttServerOptions _options;
private string _identifier;
private CancellationTokenSource _cancellationTokenSource;
private MqttApplicationMessage _willMessage;
@@ -38,7 +37,7 @@ namespace MQTTnet.Core.Server
public IMqttCommunicationAdapter Adapter { get; private set; }
public async Task RunAsync(string identifier, MqttApplicationMessage willMessage, IMqttCommunicationAdapter adapter)
public async Task RunAsync(MqttApplicationMessage willMessage, IMqttCommunicationAdapter adapter)
{
if (adapter == null) throw new ArgumentNullException(nameof(adapter));
@@ -46,7 +45,6 @@ namespace MQTTnet.Core.Server
try
{
_identifier = identifier;
Adapter = adapter;
_cancellationTokenSource = new CancellationTokenSource();
@@ -58,11 +56,11 @@ namespace MQTTnet.Core.Server
}
catch (MqttCommunicationException exception)
{
MqttTrace.Warning(nameof(MqttClientSession), exception, "Client '{0}': Communication exception while processing client packets.", _identifier);
MqttTrace.Warning(nameof(MqttClientSession), exception, "Client '{0}': Communication exception while processing client packets.", ClientId);
}
catch (Exception exception)
{
MqttTrace.Error(nameof(MqttClientSession), exception, "Client '{0}': Unhandled exception while processing client packets.", _identifier);
MqttTrace.Error(nameof(MqttClientSession), exception, "Client '{0}': Unhandled exception while processing client packets.", ClientId);
}
}
@@ -79,7 +77,7 @@ namespace MQTTnet.Core.Server
Adapter = null;
MqttTrace.Information(nameof(MqttClientSession), "Client '{0}': Disconnected.", _identifier);
MqttTrace.Information(nameof(MqttClientSession), "Client '{0}': Disconnected.", ClientId);
}
public void EnqueuePublishPacket(MqttPublishPacket publishPacket)
@@ -92,7 +90,7 @@ namespace MQTTnet.Core.Server
}
_pendingMessagesQueue.Enqueue(publishPacket);
MqttTrace.Verbose(nameof(MqttClientSession), "Client '{0}': Enqueued pending publish packet.", _identifier);
MqttTrace.Verbose(nameof(MqttClientSession), "Client '{0}': Enqueued pending publish packet.", ClientId);
}
public void Dispose()
@@ -116,12 +114,12 @@ namespace MQTTnet.Core.Server
}
catch (MqttCommunicationException exception)
{
MqttTrace.Warning(nameof(MqttClientSession), exception, "Client '{0}': Communication exception while processing client packets.", _identifier);
MqttTrace.Warning(nameof(MqttClientSession), exception, "Client '{0}': Communication exception while processing client packets.", ClientId);
Stop();
}
catch (Exception exception)
{
MqttTrace.Error(nameof(MqttClientSession), exception, "Client '{0}': Unhandled exception while processing client packets.", _identifier);
MqttTrace.Error(nameof(MqttClientSession), exception, "Client '{0}': Unhandled exception while processing client packets.", ClientId);
Stop();
}
}
@@ -163,7 +161,7 @@ namespace MQTTnet.Core.Server
}
else
{
MqttTrace.Warning(nameof(MqttClientSession), "Client '{0}': Received not supported packet ({1}). Closing connection.", _identifier, packet);
MqttTrace.Warning(nameof(MqttClientSession), "Client '{0}': Received not supported packet ({1}). Closing connection.", ClientId, packet);
_cancellationTokenSource.Cancel();
}
}
@@ -181,7 +179,7 @@ namespace MQTTnet.Core.Server
{
if (publishPacket.Retain)
{
await _mqttClientSessionsManager.RetainedMessagesManager.HandleMessageAsync(_identifier, publishPacket);
await _mqttClientSessionsManager.RetainedMessagesManager.HandleMessageAsync(ClientId, publishPacket);
}
if (publishPacket.QualityOfServiceLevel == MqttQualityOfServiceLevel.AtMostOnce)
@@ -25,16 +25,18 @@ namespace MQTTnet.Core.Server
public event EventHandler<MqttApplicationMessageReceivedEventArgs> ApplicationMessageReceived;
public event EventHandler<MqttClientConnectedEventArgs> ClientConnected;
public event EventHandler<MqttClientDisconnectedEventArgs> ClientDisconnected;
public MqttClientRetainedMessagesManager RetainedMessagesManager { get; }
public async Task RunClientSessionAsync(MqttClientConnectedEventArgs eventArgs)
public async Task RunClientSessionAsync(IMqttCommunicationAdapter clientAdapter)
{
var clientId = string.Empty;
try
{
if (!(await eventArgs.ClientAdapter.ReceivePacketAsync(_options.DefaultCommunicationTimeout, CancellationToken.None).ConfigureAwait(false) is MqttConnectPacket connectPacket))
if (!(await clientAdapter.ReceivePacketAsync(_options.DefaultCommunicationTimeout, CancellationToken.None).ConfigureAwait(false) is MqttConnectPacket connectPacket))
{
throw new MqttProtocolViolationException("The first packet from a client must be a 'CONNECT' packet [MQTT-3.1.0-1].");
}
@@ -42,12 +44,12 @@ namespace MQTTnet.Core.Server
clientId = connectPacket.ClientId;
// Switch to the required protocol version before sending any response.
eventArgs.ClientAdapter.PacketSerializer.ProtocolVersion = connectPacket.ProtocolVersion;
clientAdapter.PacketSerializer.ProtocolVersion = connectPacket.ProtocolVersion;
var connectReturnCode = ValidateConnection(connectPacket);
if (connectReturnCode != MqttConnectReturnCode.ConnectionAccepted)
{
await eventArgs.ClientAdapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, CancellationToken.None, new MqttConnAckPacket
await clientAdapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, CancellationToken.None, new MqttConnAckPacket
{
ConnectReturnCode = connectReturnCode
}).ConfigureAwait(false);
@@ -57,13 +59,19 @@ namespace MQTTnet.Core.Server
var clientSession = GetOrCreateClientSession(connectPacket);
await eventArgs.ClientAdapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, CancellationToken.None, new MqttConnAckPacket
await clientAdapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, CancellationToken.None, new MqttConnAckPacket
{
ConnectReturnCode = connectReturnCode,
IsSessionPresent = clientSession.IsExistingSession
}).ConfigureAwait(false);
await clientSession.Session.RunAsync(eventArgs.Identifier, connectPacket.WillMessage, eventArgs.ClientAdapter).ConfigureAwait(false);
ClientConnected?.Invoke(this, new MqttClientConnectedEventArgs(new ConnectedMqttClient
{
ClientId = clientId,
ProtocolVersion = clientAdapter.PacketSerializer.ProtocolVersion
}));
await clientSession.Session.RunAsync(connectPacket.WillMessage, clientAdapter).ConfigureAwait(false);
}
catch (Exception exception)
{
@@ -71,8 +79,20 @@ namespace MQTTnet.Core.Server
}
finally
{
await eventArgs.ClientAdapter.DisconnectAsync(_options.DefaultCommunicationTimeout).ConfigureAwait(false);
ClientDisconnected?.Invoke(this, new MqttClientDisconnectedEventArgs(clientId, eventArgs.ClientAdapter));
try
{
await clientAdapter.DisconnectAsync(_options.DefaultCommunicationTimeout).ConfigureAwait(false);
}
catch (Exception)
{
//ignored
}
ClientDisconnected?.Invoke(this, new MqttClientDisconnectedEventArgs(new ConnectedMqttClient
{
ClientId = clientId,
ProtocolVersion = clientAdapter.PacketSerializer.ProtocolVersion
}));
}
}
+12 -8
View File
@@ -23,6 +23,7 @@ namespace MQTTnet.Core.Server
_clientSessionsManager = new MqttClientSessionsManager(options);
_clientSessionsManager.ApplicationMessageReceived += (s, e) => ApplicationMessageReceived?.Invoke(s, e);
_clientSessionsManager.ClientConnected += OnClientConnected;
_clientSessionsManager.ClientDisconnected += OnClientDisconnected;
}
@@ -42,12 +43,12 @@ namespace MQTTnet.Core.Server
_clientSessionsManager.DispatchPublishPacket(null, applicationMessage.ToPublishPacket());
}
public void InjectClient(string identifier, IMqttCommunicationAdapter adapter)
public void InjectClient(IMqttCommunicationAdapter adapter)
{
if (adapter == null) throw new ArgumentNullException(nameof(adapter));
if (_cancellationTokenSource == null) throw new InvalidOperationException("The MQTT server is not started.");
OnClientConnected(this, new MqttClientConnectedEventArgs(identifier, adapter));
OnClientAccepted(adapter);
}
public async Task StartAsync()
@@ -60,7 +61,7 @@ namespace MQTTnet.Core.Server
foreach (var adapter in _adapters)
{
adapter.ClientConnected += OnClientConnected;
adapter.ClientAccepted += OnClientAccepted;
await adapter.StartAsync(_options);
}
@@ -75,7 +76,7 @@ namespace MQTTnet.Core.Server
foreach (var adapter in _adapters)
{
adapter.ClientConnected -= OnClientConnected;
adapter.ClientAccepted -= OnClientAccepted;
await adapter.StopAsync();
}
@@ -84,17 +85,20 @@ namespace MQTTnet.Core.Server
MqttTrace.Information(nameof(MqttServer), "Stopped.");
}
private void OnClientAccepted(IMqttCommunicationAdapter adapter)
{
Task.Run(() =>_clientSessionsManager.RunClientSessionAsync(adapter), _cancellationTokenSource.Token);
}
private void OnClientConnected(object sender, MqttClientConnectedEventArgs eventArgs)
{
MqttTrace.Information(nameof(MqttServer), "Client '{0}': Connected.", eventArgs.Identifier);
MqttTrace.Information(nameof(MqttServer), "Client '{0}': Connected.", eventArgs.Client.ClientId);
ClientConnected?.Invoke(this, eventArgs);
Task.Run(() => _clientSessionsManager.RunClientSessionAsync(eventArgs), _cancellationTokenSource.Token);
}
private void OnClientDisconnected(object sender, MqttClientDisconnectedEventArgs eventArgs)
{
MqttTrace.Information(nameof(MqttServer), "Client '{0}': Disconnected.", eventArgs.Identifier);
MqttTrace.Information(nameof(MqttServer), "Client '{0}': Disconnected.", eventArgs.Client.ClientId);
ClientDisconnected?.Invoke(this, eventArgs);
}
}