Use latest language features (#2176)

* Make use of language features line AsyncDispose, init etc.

* Fix build errors

* Improve Unit Tests

* Improve Unit Tests

* Improve Unit Tests

* Update samples

* Remove obsolete benchmarks

* Code cleanup

* Improve unit tests

* Improve Unit Tests

* Fix Unit Tests

* Improve Unit Tests

* Improve Unit Tests

* Restore unit tests

* Exclude load tests from unit tests
This commit is contained in:
Christian
2025-08-30 10:52:59 +02:00
committed by GitHub
parent 247988e633
commit e43e7f8e36
330 changed files with 21417 additions and 22919 deletions
@@ -2,26 +2,23 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace MQTTnet.Server;
namespace MQTTnet.Server
public sealed class ApplicationMessageEnqueuedEventArgs : EventArgs
{
public sealed class ApplicationMessageEnqueuedEventArgs : EventArgs
public ApplicationMessageEnqueuedEventArgs(string senderClientId, string receiverClientId, MqttApplicationMessage applicationMessage, bool isDropped)
{
public ApplicationMessageEnqueuedEventArgs(string senderClientId, string receiverClientId, MqttApplicationMessage applicationMessage, bool isDropped)
{
SenderClientId = senderClientId ?? throw new ArgumentNullException( nameof(senderClientId));
ReceiverClientId = receiverClientId ?? throw new ArgumentNullException(nameof(receiverClientId));
ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage));
IsDropped = isDropped;
}
public string SenderClientId { get; }
public string ReceiverClientId { get; }
public bool IsDropped { get; }
public MqttApplicationMessage ApplicationMessage { get; }
SenderClientId = senderClientId ?? throw new ArgumentNullException( nameof(senderClientId));
ReceiverClientId = receiverClientId ?? throw new ArgumentNullException(nameof(receiverClientId));
ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage));
IsDropped = isDropped;
}
public string SenderClientId { get; }
public string ReceiverClientId { get; }
public bool IsDropped { get; }
public MqttApplicationMessage ApplicationMessage { get; }
}
@@ -2,26 +2,23 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace MQTTnet.Server;
namespace MQTTnet.Server
public sealed class ApplicationMessageNotConsumedEventArgs : EventArgs
{
public sealed class ApplicationMessageNotConsumedEventArgs : EventArgs
public ApplicationMessageNotConsumedEventArgs(MqttApplicationMessage applicationMessage, string senderId)
{
public ApplicationMessageNotConsumedEventArgs(MqttApplicationMessage applicationMessage, string senderId)
{
ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage));
SenderId = senderId;
}
/// <summary>
/// Gets the application message which was not consumed by any client.
/// </summary>
public MqttApplicationMessage ApplicationMessage { get; }
/// <summary>
/// Gets the ID of the client which has sent the affected application message.
/// </summary>
public string SenderId { get; }
ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage));
SenderId = senderId;
}
/// <summary>
/// Gets the application message which was not consumed by any client.
/// </summary>
public MqttApplicationMessage ApplicationMessage { get; }
/// <summary>
/// Gets the ID of the client which has sent the affected application message.
/// </summary>
public string SenderId { get; }
}
@@ -2,51 +2,49 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
using MQTTnet.Packets;
namespace MQTTnet.Server
namespace MQTTnet.Server;
public sealed class ClientAcknowledgedPublishPacketEventArgs : EventArgs
{
public sealed class ClientAcknowledgedPublishPacketEventArgs : EventArgs
public ClientAcknowledgedPublishPacketEventArgs(string clientId, string userName, IDictionary sessionItems, MqttPublishPacket publishPacket, MqttPacketWithIdentifier acknowledgePacket)
{
public ClientAcknowledgedPublishPacketEventArgs(string clientId, string userName, IDictionary sessionItems, MqttPublishPacket publishPacket, MqttPacketWithIdentifier acknowledgePacket)
{
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
UserName = userName;
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
PublishPacket = publishPacket ?? throw new ArgumentNullException(nameof(publishPacket));
AcknowledgePacket = acknowledgePacket ?? throw new ArgumentNullException(nameof(acknowledgePacket));
}
/// <summary>
/// Gets the packet which was used for acknowledge. This can be a PubAck or PubComp packet.
/// </summary>
public MqttPacketWithIdentifier AcknowledgePacket { get; }
/// <summary>
/// Gets the ID of the client which acknowledged a PUBLISH packet.
/// </summary>
public string ClientId { get; }
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName { get; }
/// <summary>
/// Gets whether the PUBLISH packet is fully acknowledged. This is the case for PUBACK (QoS 1) and PUBCOMP (QoS 2.
/// </summary>
public bool IsCompleted => AcknowledgePacket is MqttPubAckPacket || AcknowledgePacket is MqttPubCompPacket;
/// <summary>
/// Gets the PUBLISH packet which was acknowledged.
/// </summary>
public MqttPublishPacket PublishPacket { get; }
/// <summary>
/// Gets the session items which contain custom user data per session.
/// </summary>
public IDictionary SessionItems { get; }
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
UserName = userName;
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
PublishPacket = publishPacket ?? throw new ArgumentNullException(nameof(publishPacket));
AcknowledgePacket = acknowledgePacket ?? throw new ArgumentNullException(nameof(acknowledgePacket));
}
/// <summary>
/// Gets the packet which was used for acknowledge. This can be a PubAck or PubComp packet.
/// </summary>
public MqttPacketWithIdentifier AcknowledgePacket { get; }
/// <summary>
/// Gets the ID of the client which acknowledged a PUBLISH packet.
/// </summary>
public string ClientId { get; }
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName { get; }
/// <summary>
/// Gets whether the PUBLISH packet is fully acknowledged. This is the case for PUBACK (QoS 1) and PUBCOMP (QoS 2.
/// </summary>
public bool IsCompleted => AcknowledgePacket is MqttPubAckPacket || AcknowledgePacket is MqttPubCompPacket;
/// <summary>
/// Gets the PUBLISH packet which was acknowledged.
/// </summary>
public MqttPublishPacket PublishPacket { get; }
/// <summary>
/// Gets the session items which contain custom user data per session.
/// </summary>
public IDictionary SessionItems { get; }
}
@@ -2,70 +2,67 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Text;
using MQTTnet.Formatter;
using MQTTnet.Packets;
namespace MQTTnet.Server
namespace MQTTnet.Server;
public sealed class ClientConnectedEventArgs : EventArgs
{
public sealed class ClientConnectedEventArgs : EventArgs
readonly MqttConnectPacket _connectPacket;
public ClientConnectedEventArgs(MqttConnectPacket connectPacket, MqttProtocolVersion protocolVersion, EndPoint remoteEndPoint, IDictionary sessionItems)
{
readonly MqttConnectPacket _connectPacket;
public ClientConnectedEventArgs(MqttConnectPacket connectPacket, MqttProtocolVersion protocolVersion, EndPoint remoteEndPoint, IDictionary sessionItems)
{
_connectPacket = connectPacket ?? throw new ArgumentNullException(nameof(connectPacket));
ProtocolVersion = protocolVersion;
RemoteEndPoint = remoteEndPoint;
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
}
public byte[] AuthenticationData => _connectPacket.AuthenticationData;
public string AuthenticationMethod => _connectPacket.AuthenticationMethod;
/// <summary>
/// Gets the client identifier of the connected client.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
public string ClientId => _connectPacket.ClientId;
/// <summary>
/// Gets the endpoint of the connected client.
/// </summary>
public EndPoint RemoteEndPoint { get; }
[Obsolete("Use RemoteEndPoint instead.")]
public string Endpoint => RemoteEndPoint?.ToString();
/// <summary>
/// Gets the protocol version which is used by the connected client.
/// </summary>
public MqttProtocolVersion ProtocolVersion { get; }
/// <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 name of the connected client.
/// </summary>
public string UserName => _connectPacket.Username;
/// <summary>
/// Gets the password of the connected client.
/// </summary>
public string Password => Encoding.UTF8.GetString(_connectPacket.Password.AsSpan());
/// <summary>
/// Gets the user properties sent by the client.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public List<MqttUserProperty> UserProperties => _connectPacket?.UserProperties;
_connectPacket = connectPacket ?? throw new ArgumentNullException(nameof(connectPacket));
ProtocolVersion = protocolVersion;
RemoteEndPoint = remoteEndPoint;
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
}
public byte[] AuthenticationData => _connectPacket.AuthenticationData;
public string AuthenticationMethod => _connectPacket.AuthenticationMethod;
/// <summary>
/// Gets the client identifier of the connected client.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
public string ClientId => _connectPacket.ClientId;
/// <summary>
/// Gets the endpoint of the connected client.
/// </summary>
public EndPoint RemoteEndPoint { get; }
[Obsolete("Use RemoteEndPoint instead.")]
public string Endpoint => RemoteEndPoint?.ToString();
/// <summary>
/// Gets the protocol version which is used by the connected client.
/// </summary>
public MqttProtocolVersion ProtocolVersion { get; }
/// <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 name of the connected client.
/// </summary>
public string UserName => _connectPacket.Username;
/// <summary>
/// Gets the password of the connected client.
/// </summary>
public string Password => Encoding.UTF8.GetString(_connectPacket.Password.AsSpan());
/// <summary>
/// Gets the user properties sent by the client.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public List<MqttUserProperty> UserProperties => _connectPacket?.UserProperties;
}
@@ -2,91 +2,88 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Text;
using MQTTnet.Packets;
using MQTTnet.Protocol;
namespace MQTTnet.Server
namespace MQTTnet.Server;
public sealed class ClientDisconnectedEventArgs : EventArgs
{
public sealed class ClientDisconnectedEventArgs : EventArgs
readonly MqttConnectPacket _connectPacket;
readonly MqttDisconnectPacket _disconnectPacket;
public ClientDisconnectedEventArgs(
MqttConnectPacket connectPacket,
MqttDisconnectPacket disconnectPacket,
MqttClientDisconnectType disconnectType,
EndPoint remoteEndPoint,
IDictionary sessionItems)
{
readonly MqttConnectPacket _connectPacket;
readonly MqttDisconnectPacket _disconnectPacket;
DisconnectType = disconnectType;
RemoteEndPoint = remoteEndPoint;
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
public ClientDisconnectedEventArgs(
MqttConnectPacket connectPacket,
MqttDisconnectPacket disconnectPacket,
MqttClientDisconnectType disconnectType,
EndPoint remoteEndPoint,
IDictionary sessionItems)
{
DisconnectType = disconnectType;
RemoteEndPoint = remoteEndPoint;
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
_connectPacket = connectPacket;
// The DISCONNECT packet can be null in case of a non clean disconnect or session takeover.
_disconnectPacket = disconnectPacket;
}
/// <summary>
/// Gets the client identifier.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
public string ClientId => _connectPacket.ClientId;
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName => _connectPacket.Username;
/// <summary>
/// Gets the password of the client.
/// </summary>
public string Password => Encoding.UTF8.GetString(_connectPacket.Password.AsSpan());
public MqttClientDisconnectType DisconnectType { get; }
public EndPoint RemoteEndPoint { get; }
[Obsolete("Use RemoteEndPoint instead.")]
public string Endpoint => RemoteEndPoint?.ToString();
/// <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;
_connectPacket = connectPacket;
// The DISCONNECT packet can be null in case of a non clean disconnect or session takeover.
_disconnectPacket = disconnectPacket;
}
/// <summary>
/// Gets the client identifier.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
public string ClientId => _connectPacket.ClientId;
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName => _connectPacket.Username;
/// <summary>
/// Gets the password of the client.
/// </summary>
public string Password => Encoding.UTF8.GetString(_connectPacket.Password.AsSpan());
public MqttClientDisconnectType DisconnectType { get; }
public EndPoint RemoteEndPoint { get; }
[Obsolete("Use RemoteEndPoint instead.")]
public string Endpoint => RemoteEndPoint?.ToString();
/// <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;
}
@@ -2,42 +2,40 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
using MQTTnet.Packets;
namespace MQTTnet.Server
namespace MQTTnet.Server;
public sealed class ClientSubscribedTopicEventArgs : EventArgs
{
public sealed class ClientSubscribedTopicEventArgs : EventArgs
public ClientSubscribedTopicEventArgs(string clientId, string userName, MqttTopicFilter topicFilter, IDictionary sessionItems)
{
public ClientSubscribedTopicEventArgs(string clientId, string userName, MqttTopicFilter topicFilter, IDictionary sessionItems)
{
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
UserName = userName;
TopicFilter = topicFilter ?? throw new ArgumentNullException(nameof(topicFilter));
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
}
/// <summary>
/// Gets the client identifier.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
public string ClientId { get; }
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName { get; }
/// <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 topic filter.
/// The topic filter can contain topics and wildcards.
/// </summary>
public MqttTopicFilter TopicFilter { get; }
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
UserName = userName;
TopicFilter = topicFilter ?? throw new ArgumentNullException(nameof(topicFilter));
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
}
/// <summary>
/// Gets the client identifier.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
public string ClientId { get; }
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName { get; }
/// <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 topic filter.
/// The topic filter can contain topics and wildcards.
/// </summary>
public MqttTopicFilter TopicFilter { get; }
}
@@ -2,41 +2,39 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
namespace MQTTnet.Server
namespace MQTTnet.Server;
public sealed class ClientUnsubscribedTopicEventArgs : EventArgs
{
public sealed class ClientUnsubscribedTopicEventArgs : EventArgs
public ClientUnsubscribedTopicEventArgs(string clientId, string userName, string topicFilter, IDictionary sessionItems)
{
public ClientUnsubscribedTopicEventArgs(string clientId, string userName, string topicFilter, IDictionary sessionItems)
{
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
UserName = userName;
TopicFilter = topicFilter ?? throw new ArgumentNullException(nameof(topicFilter));
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
}
/// <summary>
/// Gets the client identifier.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
public string ClientId { get; }
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName { get; }
/// <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 or sets the topic filter.
/// The topic filter can contain topics and wildcards.
/// </summary>
public string TopicFilter { get; }
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
UserName = userName;
TopicFilter = topicFilter ?? throw new ArgumentNullException(nameof(topicFilter));
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
}
/// <summary>
/// Gets the client identifier.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
public string ClientId { get; }
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName { get; }
/// <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 or sets the topic filter.
/// The topic filter can contain topics and wildcards.
/// </summary>
public string TopicFilter { get; }
}
@@ -2,34 +2,31 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace MQTTnet.Server;
namespace MQTTnet.Server
public sealed class InterceptingClientApplicationMessageEnqueueEventArgs : EventArgs
{
public sealed class InterceptingClientApplicationMessageEnqueueEventArgs : EventArgs
public InterceptingClientApplicationMessageEnqueueEventArgs(string senderClientId, string receiverClientId, MqttApplicationMessage applicationMessage)
{
public InterceptingClientApplicationMessageEnqueueEventArgs(string senderClientId, string receiverClientId, MqttApplicationMessage applicationMessage)
{
SenderClientId = senderClientId ?? throw new ArgumentNullException(nameof(senderClientId));
ReceiverClientId = receiverClientId ?? throw new ArgumentNullException(nameof(receiverClientId));
ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage));
}
/// <summary>
/// Gets or sets whether the enqueue of the application message should be performed or not.
/// If set to _False_ the client will not receive the application message.
/// </summary>
public bool AcceptEnqueue { get; set; } = true;
public MqttApplicationMessage ApplicationMessage { get; }
/// <summary>
/// Indicates if the connection with the sender should be closed.
/// </summary>
public bool CloseSenderConnection { get; set; }
public string ReceiverClientId { get; }
public string SenderClientId { get; }
SenderClientId = senderClientId ?? throw new ArgumentNullException(nameof(senderClientId));
ReceiverClientId = receiverClientId ?? throw new ArgumentNullException(nameof(receiverClientId));
ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage));
}
/// <summary>
/// Gets or sets whether the enqueue of the application message should be performed or not.
/// If set to _False_ the client will not receive the application message.
/// </summary>
public bool AcceptEnqueue { get; set; } = true;
public MqttApplicationMessage ApplicationMessage { get; }
/// <summary>
/// Indicates if the connection with the sender should be closed.
/// </summary>
public bool CloseSenderConnection { get; set; }
public string ReceiverClientId { get; }
public string SenderClientId { get; }
}
@@ -2,63 +2,60 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
using System.Net;
using System.Threading;
using MQTTnet.Packets;
namespace MQTTnet.Server
namespace MQTTnet.Server;
public sealed class InterceptingPacketEventArgs : EventArgs
{
public sealed class InterceptingPacketEventArgs : EventArgs
public InterceptingPacketEventArgs(CancellationToken cancellationToken, string clientId, string userName, EndPoint remoteEndPoint, MqttPacket packet, IDictionary sessionItems)
{
public InterceptingPacketEventArgs(CancellationToken cancellationToken, string clientId, string userName, EndPoint remoteEndPoint, MqttPacket packet, IDictionary sessionItems)
{
CancellationToken = cancellationToken;
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
UserName = userName;
RemoteEndPoint = remoteEndPoint;
Packet = packet ?? throw new ArgumentNullException(nameof(packet));
SessionItems = sessionItems;
}
/// <summary>
/// Gets the cancellation token from the connection managing thread.
/// Use this in further event processing.
/// </summary>
public CancellationToken CancellationToken { get; }
/// <summary>
/// Gets the client ID which has sent the packet or will receive the packet.
/// </summary>
public string ClientId { get; }
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName { get; }
/// <summary>
/// Gets the endpoint of the sending or receiving client.
/// </summary>
public EndPoint RemoteEndPoint { get; }
[Obsolete("Use RemoteEndPoint instead.")]
public string Endpoint => RemoteEndPoint?.ToString();
/// <summary>
/// Gets or sets the MQTT packet which was received or will be sent.
/// </summary>
public MqttPacket Packet { get; set; }
/// <summary>
/// Gets or sets whether the packet should be processed or not.
/// </summary>
public bool ProcessPacket { get; set; } = true;
/// <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; }
CancellationToken = cancellationToken;
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
UserName = userName;
RemoteEndPoint = remoteEndPoint;
Packet = packet ?? throw new ArgumentNullException(nameof(packet));
SessionItems = sessionItems;
}
/// <summary>
/// Gets the cancellation token from the connection managing thread.
/// Use this in further event processing.
/// </summary>
public CancellationToken CancellationToken { get; }
/// <summary>
/// Gets the client ID which has sent the packet or will receive the packet.
/// </summary>
public string ClientId { get; }
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName { get; }
/// <summary>
/// Gets the endpoint of the sending or receiving client.
/// </summary>
public EndPoint RemoteEndPoint { get; }
[Obsolete("Use RemoteEndPoint instead.")]
public string Endpoint => RemoteEndPoint?.ToString();
/// <summary>
/// Gets or sets the MQTT packet which was received or will be sent.
/// </summary>
public MqttPacket Packet { get; set; }
/// <summary>
/// Gets or sets whether the packet should be processed or not.
/// </summary>
public bool ProcessPacket { get; set; } = true;
/// <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; }
}
@@ -2,56 +2,53 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
using System.Threading;
namespace MQTTnet.Server
namespace MQTTnet.Server;
public sealed class InterceptingPublishEventArgs : EventArgs
{
public sealed class InterceptingPublishEventArgs : EventArgs
public InterceptingPublishEventArgs(MqttApplicationMessage applicationMessage, CancellationToken cancellationToken, string clientId, string userName, IDictionary sessionItems)
{
public InterceptingPublishEventArgs(MqttApplicationMessage applicationMessage, CancellationToken cancellationToken, string clientId, string userName, IDictionary sessionItems)
{
ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage));
CancellationToken = cancellationToken;
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
UserName = userName;
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
}
public MqttApplicationMessage ApplicationMessage { get; set; }
/// <summary>
/// Gets the cancellation token which can indicate that the client connection gets down.
/// </summary>
public CancellationToken CancellationToken { get; }
/// <summary>
/// Gets the client identifier.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
public string ClientId { get; }
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName { get; }
public bool CloseConnection { get; set; }
/// <summary>
/// Gets or sets whether the publish should be processed internally.
/// </summary>
public bool ProcessPublish { get; set; } = true;
/// <summary>
/// Gets the response which will be sent to the client via the PUBACK etc. packets.
/// </summary>
public PublishResponse Response { get; } = new PublishResponse();
/// <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; }
ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage));
CancellationToken = cancellationToken;
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
UserName = userName;
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
}
public MqttApplicationMessage ApplicationMessage { get; set; }
/// <summary>
/// Gets the cancellation token which can indicate that the client connection gets down.
/// </summary>
public CancellationToken CancellationToken { get; }
/// <summary>
/// Gets the client identifier.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
public string ClientId { get; }
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName { get; }
public bool CloseConnection { get; set; }
/// <summary>
/// Gets or sets whether the publish should be processed internally.
/// </summary>
public bool ProcessPublish { get; set; } = true;
/// <summary>
/// Gets the response which will be sent to the client via the PUBACK etc. packets.
/// </summary>
public PublishResponse Response { get; } = new PublishResponse();
/// <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; }
}
@@ -2,90 +2,86 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using MQTTnet.Packets;
namespace MQTTnet.Server
namespace MQTTnet.Server;
public sealed class InterceptingSubscriptionEventArgs : EventArgs
{
public sealed class InterceptingSubscriptionEventArgs : EventArgs
public InterceptingSubscriptionEventArgs(
CancellationToken cancellationToken,
string clientId,
string userName,
MqttSessionStatus session,
MqttTopicFilter topicFilter,
List<MqttUserProperty> userProperties)
{
public InterceptingSubscriptionEventArgs(
CancellationToken cancellationToken,
string clientId,
string userName,
MqttSessionStatus session,
MqttTopicFilter topicFilter,
List<MqttUserProperty> userProperties)
{
CancellationToken = cancellationToken;
ClientId = clientId;
UserName = userName;
Session = session;
TopicFilter = topicFilter;
UserProperties = userProperties;
}
/// <summary>
/// Gets the cancellation token which can indicate that the client connection gets down.
/// </summary>
public CancellationToken CancellationToken { get; }
/// <summary>
/// Gets the client identifier.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
public string ClientId { get; }
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName { get; }
/// <summary>
/// Gets or sets whether the broker should close the client connection.
/// </summary>
public bool CloseConnection { get; set; }
/// <summary>
/// Gets or sets whether the broker should create an internal subscription for the client.
/// The broker can also avoid this and return "success" to the client.
/// This feature allows using the MQTT Broker as the Frontend and another system as the backend.
/// </summary>
public bool ProcessSubscription { get; set; } = true;
/// <summary>
/// Gets or sets the reason string which will be sent to the client in the SUBACK packet.
/// </summary>
public string ReasonString { get; set; }
/// <summary>
/// Gets the response which will be sent to the client via the SUBACK packet.
/// </summary>
public SubscribeResponse Response { get; } = new SubscribeResponse();
/// <summary>
/// Gets the current client session.
/// </summary>
public MqttSessionStatus Session { get; }
/// <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 => Session.Items;
/// <summary>
/// Gets or sets the topic filter.
/// The topic filter can contain topics and wildcards.
/// </summary>
public MqttTopicFilter TopicFilter { get; set; }
/// <summary>
/// Gets or sets the user properties.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public List<MqttUserProperty> UserProperties { get; set; }
CancellationToken = cancellationToken;
ClientId = clientId;
UserName = userName;
Session = session;
TopicFilter = topicFilter;
UserProperties = userProperties;
}
/// <summary>
/// Gets the cancellation token which can indicate that the client connection gets down.
/// </summary>
public CancellationToken CancellationToken { get; }
/// <summary>
/// Gets the client identifier.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
public string ClientId { get; }
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName { get; }
/// <summary>
/// Gets or sets whether the broker should close the client connection.
/// </summary>
public bool CloseConnection { get; set; }
/// <summary>
/// Gets or sets whether the broker should create an internal subscription for the client.
/// The broker can also avoid this and return "success" to the client.
/// This feature allows using the MQTT Broker as the Frontend and another system as the backend.
/// </summary>
public bool ProcessSubscription { get; set; } = true;
/// <summary>
/// Gets or sets the reason string which will be sent to the client in the SUBACK packet.
/// </summary>
public string ReasonString { get; set; }
/// <summary>
/// Gets the response which will be sent to the client via the SUBACK packet.
/// </summary>
public SubscribeResponse Response { get; } = new SubscribeResponse();
/// <summary>
/// Gets the current client session.
/// </summary>
public MqttSessionStatus Session { get; }
/// <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 => Session.Items;
/// <summary>
/// Gets or sets the topic filter.
/// The topic filter can contain topics and wildcards.
/// </summary>
public MqttTopicFilter TopicFilter { get; set; }
/// <summary>
/// Gets or sets the user properties.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public List<MqttUserProperty> UserProperties { get; set; }
}
@@ -2,77 +2,73 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using MQTTnet.Packets;
namespace MQTTnet.Server
namespace MQTTnet.Server;
public sealed class InterceptingUnsubscriptionEventArgs : EventArgs
{
public sealed class InterceptingUnsubscriptionEventArgs : EventArgs
public InterceptingUnsubscriptionEventArgs(CancellationToken cancellationToken, string clientId, string userName, IDictionary sessionItems, string topic, List<MqttUserProperty> userProperties)
{
public InterceptingUnsubscriptionEventArgs(CancellationToken cancellationToken, string clientId, string userName, IDictionary sessionItems, string topic, List<MqttUserProperty> userProperties)
{
CancellationToken = cancellationToken;
ClientId = clientId;
UserName = userName;
SessionItems = sessionItems;
Topic = topic;
UserProperties = userProperties;
}
/// <summary>
/// Gets the cancellation token which can indicate that the client connection gets down.
/// </summary>
public CancellationToken CancellationToken { get; }
/// <summary>
/// Gets the client identifier.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
public string ClientId { get; }
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName { get; }
/// <summary>
/// Gets or sets whether the broker should close the client connection.
/// </summary>
public bool CloseConnection { get; set; }
/// <summary>
/// Gets or sets whether the broker should remove an internal subscription for the client.
/// The broker can also avoid this and return "success" to the client.
/// This feature allows using the MQTT Broker as the Frontend and another system as the backend.
/// </summary>
public bool ProcessUnsubscription { get; set; } = true;
/// <summary>
/// Gets the response which will be sent to the client via the UNSUBACK pocket.
/// </summary>
public UnsubscribeResponse Response { get; } = new UnsubscribeResponse();
/// <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 or sets the MQTT topic.
/// In MQTT, the word topic refers to an UTF-8 string that the broker uses to filter messages for each connected
/// client.
/// The topic consists of one or more topic levels. Each topic level is separated by a forward slash (topic level
/// separator).
/// </summary>
public string Topic { get; }
/// <summary>
/// Gets or sets the user properties.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public List<MqttUserProperty> UserProperties { get; set; }
CancellationToken = cancellationToken;
ClientId = clientId;
UserName = userName;
SessionItems = sessionItems;
Topic = topic;
UserProperties = userProperties;
}
/// <summary>
/// Gets the cancellation token which can indicate that the client connection gets down.
/// </summary>
public CancellationToken CancellationToken { get; }
/// <summary>
/// Gets the client identifier.
/// Hint: This identifier needs to be unique over all used clients / devices on the broker to avoid connection issues.
/// </summary>
public string ClientId { get; }
/// <summary>
/// Gets the user name of the client.
/// </summary>
public string UserName { get; }
/// <summary>
/// Gets or sets whether the broker should close the client connection.
/// </summary>
public bool CloseConnection { get; set; }
/// <summary>
/// Gets or sets whether the broker should remove an internal subscription for the client.
/// The broker can also avoid this and return "success" to the client.
/// This feature allows using the MQTT Broker as the Frontend and another system as the backend.
/// </summary>
public bool ProcessUnsubscription { get; set; } = true;
/// <summary>
/// Gets the response which will be sent to the client via the UNSUBACK pocket.
/// </summary>
public UnsubscribeResponse Response { get; } = new UnsubscribeResponse();
/// <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 or sets the MQTT topic.
/// In MQTT, the word topic refers to an UTF-8 string that the broker uses to filter messages for each connected
/// client.
/// The topic consists of one or more topic levels. Each topic level is separated by a forward slash (topic level
/// separator).
/// </summary>
public string Topic { get; }
/// <summary>
/// Gets or sets the user properties.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public List<MqttUserProperty> UserProperties { get; set; }
}
@@ -2,13 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
namespace MQTTnet.Server;
namespace MQTTnet.Server
public sealed class LoadingRetainedMessagesEventArgs : EventArgs
{
public sealed class LoadingRetainedMessagesEventArgs : EventArgs
{
public List<MqttApplicationMessage> LoadedRetainedMessages { get; set; } = new List<MqttApplicationMessage>();
}
public List<MqttApplicationMessage> LoadedRetainedMessages { get; set; } = new List<MqttApplicationMessage>();
}
@@ -2,50 +2,47 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using MQTTnet.Packets;
using MQTTnet.Server.Internal;
namespace MQTTnet.Server
namespace MQTTnet.Server;
public sealed class PreparingSessionEventArgs : EventArgs
{
public sealed class PreparingSessionEventArgs : EventArgs
{
public string Id { get; set; }
public string Id { get; set; }
// TODO: Allow adding of packets to the queue etc.
// TODO: Allow adding of packets to the queue etc.
/*
* The Session State in the Server consists of:
/*
* The Session State in the Server consists of:
· The existence of a Session, even if the rest of the Session State is empty.
· The Clients subscriptions, including any Subscription Identifiers.
· QoS 1 and QoS 2 messages which have been sent to the Client, but have not been completely acknowledged.
· QoS 1 and QoS 2 messages pending transmission to the Client and OPTIONALLY QoS 0 messages pending transmission to the Client.
· QoS 2 messages which have been received from the Client, but have not been completely acknowledged.The Will Message and the Will Delay Interval
· If the Session is currently not connected, the time at which the Session will end and Session State will be discarded.
*/
*/
public bool IsExistingSession { get; set; }
public bool IsExistingSession { get; set; }
public IDictionary<object, object> Items { get; set; }
public IDictionary<object, object> Items { get; set; }
public List<MqttPublishPacket> PublishPackets { get; } = new List<MqttPublishPacket>();
public List<MqttPublishPacket> PublishPackets { get; } = new List<MqttPublishPacket>();
DateTime? SessionExpiryTimestamp { get; set; }
DateTime? SessionExpiryTimestamp { get; set; }
public List<MqttSubscription> Subscriptions { get; } = new List<MqttSubscription>();
public List<MqttSubscription> Subscriptions { get; } = new List<MqttSubscription>();
/// <summary>
/// Gets the will delay interval.
/// This is the time between the client disconnect and the time the will message will be sent.
/// </summary>
public uint? WillDelayInterval { get; set; }
/// <summary>
/// Gets the will delay interval.
/// This is the time between the client disconnect and the time the will message will be sent.
/// </summary>
public uint? WillDelayInterval { get; set; }
// <summary>
// Gets the last will message.
// In MQTT, you use the last will message feature to notify other clients about an ungracefully disconnected client.
// </summary>
// TODO: Use single properties. No entire will message.
//MqttApplicationMessage WillMessage { get; set; }
}
// <summary>
// Gets the last will message.
// In MQTT, you use the last will message feature to notify other clients about an ungracefully disconnected client.
// </summary>
// TODO: Use single properties. No entire will message.
//MqttApplicationMessage WillMessage { get; set; }
}
@@ -2,21 +2,19 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using MQTTnet.Packets;
namespace MQTTnet.Server
namespace MQTTnet.Server;
public sealed class QueueMessageOverwrittenEventArgs : EventArgs
{
public sealed class QueueMessageOverwrittenEventArgs : EventArgs
public QueueMessageOverwrittenEventArgs(string receiverClientId, MqttPacket packet)
{
public QueueMessageOverwrittenEventArgs(string receiverClientId, MqttPacket packet)
{
ReceiverClientId = receiverClientId ?? throw new ArgumentNullException(nameof(receiverClientId));
Packet = packet ?? throw new ArgumentNullException(nameof(packet));
}
public MqttPacket Packet { get; }
public string ReceiverClientId { get; }
ReceiverClientId = receiverClientId ?? throw new ArgumentNullException(nameof(receiverClientId));
Packet = packet ?? throw new ArgumentNullException(nameof(packet));
}
public MqttPacket Packet { get; }
public string ReceiverClientId { get; }
}
@@ -2,24 +2,20 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
namespace MQTTnet.Server;
namespace MQTTnet.Server
public sealed class RetainedMessageChangedEventArgs : EventArgs
{
public sealed class RetainedMessageChangedEventArgs : EventArgs
public RetainedMessageChangedEventArgs(string clientId, MqttApplicationMessage changedRetainedMessage, List<MqttApplicationMessage> storedRetainedMessages)
{
public RetainedMessageChangedEventArgs(string clientId, MqttApplicationMessage changedRetainedMessage, List<MqttApplicationMessage> storedRetainedMessages)
{
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
ChangedRetainedMessage = changedRetainedMessage ?? throw new ArgumentNullException(nameof(changedRetainedMessage));
StoredRetainedMessages = storedRetainedMessages ?? throw new ArgumentNullException(nameof(storedRetainedMessages));
}
public MqttApplicationMessage ChangedRetainedMessage { get; }
public string ClientId { get; }
public List<MqttApplicationMessage> StoredRetainedMessages { get; }
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
ChangedRetainedMessage = changedRetainedMessage ?? throw new ArgumentNullException(nameof(changedRetainedMessage));
StoredRetainedMessages = storedRetainedMessages ?? throw new ArgumentNullException(nameof(storedRetainedMessages));
}
public MqttApplicationMessage ChangedRetainedMessage { get; }
public string ClientId { get; }
public List<MqttApplicationMessage> StoredRetainedMessages { get; }
}
@@ -2,33 +2,31 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
namespace MQTTnet.Server
namespace MQTTnet.Server;
public sealed class SessionDeletedEventArgs : EventArgs
{
public sealed class SessionDeletedEventArgs : EventArgs
public SessionDeletedEventArgs(string id, string userName, IDictionary sessionItems)
{
public SessionDeletedEventArgs(string id, string userName, IDictionary sessionItems)
{
Id = id ?? throw new ArgumentNullException(nameof(id));
UserName = userName;
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
}
/// <summary>
/// Gets the ID of the session.
/// </summary>
public string Id { get; }
/// <summary>
/// Gets the user name of the session.
/// </summary>
public string UserName { get; }
/// <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; }
Id = id ?? throw new ArgumentNullException(nameof(id));
UserName = userName;
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
}
/// <summary>
/// Gets the ID of the session.
/// </summary>
public string Id { get; }
/// <summary>
/// Gets the user name of the session.
/// </summary>
public string UserName { get; }
/// <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; }
}