mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-19 19:13:11 +08:00
improved client livetime events
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user