mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-18 02:13:00 +08:00
More options for disconnect (#1557)
* Expose more options in disconnect options. * Expose more options in disconnect API. * Refactor code. * Expose user properties in disconnected event. * Expose more disconnect options in server. * Fix build errors * Add new samples. * Fix client cleanup * Fix merge conflicts
This commit is contained in:
@@ -4,17 +4,30 @@
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using MQTTnet.Packets;
|
||||
using MQTTnet.Protocol;
|
||||
|
||||
namespace MQTTnet.Server
|
||||
{
|
||||
public sealed class ClientDisconnectedEventArgs : EventArgs
|
||||
{
|
||||
public ClientDisconnectedEventArgs(string clientId, MqttClientDisconnectType disconnectType, string endpoint, IDictionary sessionItems)
|
||||
readonly MqttDisconnectPacket _disconnectPacket;
|
||||
|
||||
public ClientDisconnectedEventArgs(
|
||||
string clientId,
|
||||
MqttDisconnectPacket disconnectPacket,
|
||||
MqttClientDisconnectType disconnectType,
|
||||
string endpoint,
|
||||
IDictionary sessionItems)
|
||||
{
|
||||
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
|
||||
DisconnectType = disconnectType;
|
||||
Endpoint = endpoint;
|
||||
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
|
||||
|
||||
// The DISCONNECT packet can be null in case of a non clean disconnect or session takeover.
|
||||
_disconnectPacket = disconnectPacket;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -27,9 +40,37 @@ namespace MQTTnet.Server
|
||||
|
||||
public string Endpoint { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the reason code sent by the client.
|
||||
/// Only available for clean disconnects.
|
||||
/// <remarks>MQTT 5.0.0+ feature.</remarks>
|
||||
/// </summary>
|
||||
public MqttDisconnectReasonCode? ReasonCode => _disconnectPacket?.ReasonCode;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the reason string sent by the client.
|
||||
/// Only available for clean disconnects.
|
||||
/// <remarks>MQTT 5.0.0+ feature.</remarks>
|
||||
/// </summary>
|
||||
public string ReasonString => _disconnectPacket?.ReasonString;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the session expiry interval sent by the client.
|
||||
/// Only available for clean disconnects.
|
||||
/// <remarks>MQTT 5.0.0+ feature.</remarks>
|
||||
/// </summary>
|
||||
public uint SessionExpiryInterval => _disconnectPacket?.SessionExpiryInterval ?? 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a key/value collection that can be used to share data within the scope of this session.
|
||||
/// </summary>
|
||||
public IDictionary SessionItems { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user properties sent by the client.
|
||||
/// Only available for clean disconnects.
|
||||
/// <remarks>MQTT 5.0.0+ feature.</remarks>
|
||||
/// </summary>
|
||||
public List<MqttUserProperty> UserProperties => _disconnectPacket?.UserProperties;
|
||||
}
|
||||
}
|
||||
@@ -57,12 +57,12 @@ namespace MQTTnet.Server
|
||||
|
||||
public IMqttChannelAdapter ChannelAdapter { get; }
|
||||
|
||||
public MqttDisconnectPacket DisconnectPacket { get; set; }
|
||||
|
||||
public string Endpoint { get; }
|
||||
|
||||
public string Id => _connectPacket.ClientId;
|
||||
|
||||
public bool IsCleanDisconnect { get; private set; }
|
||||
|
||||
public bool IsRunning { get; private set; }
|
||||
|
||||
public bool IsTakenOver { get; set; }
|
||||
@@ -95,8 +95,7 @@ namespace MQTTnet.Server
|
||||
{
|
||||
var cancellationToken = _cancellationToken.Token;
|
||||
|
||||
_ = Task.Factory.StartNew(() => SendPacketsLoop(cancellationToken), cancellationToken, TaskCreationOptions.PreferFairness, TaskScheduler.Default)
|
||||
.ConfigureAwait(false);
|
||||
_ = Task.Factory.StartNew(() => SendPacketsLoop(cancellationToken), cancellationToken, TaskCreationOptions.PreferFairness, TaskScheduler.Default).ConfigureAwait(false);
|
||||
|
||||
IsRunning = true;
|
||||
|
||||
@@ -111,7 +110,9 @@ namespace MQTTnet.Server
|
||||
_cancellationToken = null;
|
||||
}
|
||||
|
||||
if (!IsTakenOver && !IsCleanDisconnect && Session.LatestConnectPacket.WillFlag && !Session.WillMessageSent)
|
||||
var isCleanDisconnect = DisconnectPacket != null;
|
||||
|
||||
if (!IsTakenOver && !isCleanDisconnect && Session.LatestConnectPacket.WillFlag && !Session.WillMessageSent)
|
||||
{
|
||||
var willPublishPacket = MqttPacketFactories.Publish.Create(Session.LatestConnectPacket);
|
||||
var willApplicationMessage = MqttApplicationMessageFactory.Create(willPublishPacket);
|
||||
@@ -431,9 +432,9 @@ namespace MQTTnet.Server
|
||||
{
|
||||
throw new MqttProtocolViolationException("A PINGRESP Packet is sent by the Server to the Client in response to a PINGREQ Packet only.");
|
||||
}
|
||||
else if (currentPacket is MqttDisconnectPacket)
|
||||
else if (currentPacket is MqttDisconnectPacket disconnectPacket)
|
||||
{
|
||||
IsCleanDisconnect = true;
|
||||
DisconnectPacket = disconnectPacket;
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -387,8 +387,8 @@ namespace MQTTnet.Server
|
||||
|
||||
if (client.Id != null && !client.IsTakenOver && _eventContainer.ClientDisconnectedEvent.HasHandlers)
|
||||
{
|
||||
var disconnectType = client.IsCleanDisconnect ? MqttClientDisconnectType.Clean : MqttClientDisconnectType.NotClean;
|
||||
var eventArgs = new ClientDisconnectedEventArgs(client.Id, disconnectType, endpoint, client.Session.Items);
|
||||
var disconnectType = client.DisconnectPacket != null ? MqttClientDisconnectType.Clean : MqttClientDisconnectType.NotClean;
|
||||
var eventArgs = new ClientDisconnectedEventArgs(client.Id, client.DisconnectPacket, disconnectType, endpoint, client.Session.Items);
|
||||
|
||||
await _eventContainer.ClientDisconnectedEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
|
||||
}
|
||||
@@ -592,8 +592,13 @@ namespace MQTTnet.Server
|
||||
|
||||
if (_eventContainer.ClientDisconnectedEvent.HasHandlers)
|
||||
{
|
||||
var eventArgs = new ClientDisconnectedEventArgs(oldClient.Id, MqttClientDisconnectType.Takeover, oldClient.Endpoint, oldClient.Session.Items);
|
||||
|
||||
var eventArgs = new ClientDisconnectedEventArgs(
|
||||
oldClient.Id,
|
||||
null,
|
||||
MqttClientDisconnectType.Takeover,
|
||||
oldClient.Endpoint,
|
||||
oldClient.Session.Items);
|
||||
|
||||
await _eventContainer.ClientDisconnectedEvent.TryInvokeAsync(eventArgs, _logger).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user