diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec
index 42042a0e..505dbeb1 100644
--- a/Build/MQTTnet.nuspec
+++ b/Build/MQTTnet.nuspec
@@ -13,6 +13,9 @@
MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker) and supports v3.1.0, v3.1.1 and v5.0.0 of the MQTT protocol.
* [Core] Added support for TLS 1.3 (requires .NET Core 3.1+) (thanks to @Dvergatal).
+* [Server] Reduced async tasks count by moving dedicated keep alive tasks per connection to shared one.
+* [Server] Session takeover and keep alive timeout are now properly set in DISCONNECT packet.
+* [Server] Performance improvements.
Copyright Christian Kratky 2016-2020
MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin Blazor
diff --git a/Source/MQTTnet/Server/MqttClientConnection.cs b/Source/MQTTnet/Server/MqttClientConnection.cs
index b12d4139..07c1825e 100644
--- a/Source/MQTTnet/Server/MqttClientConnection.cs
+++ b/Source/MQTTnet/Server/MqttClientConnection.cs
@@ -41,6 +41,7 @@ namespace MQTTnet.Server
long _sentPacketsCount = 1; // Start with 1 because the CONNECT packet is not counted anywhere.
long _receivedApplicationMessagesCount;
long _sentApplicationMessagesCount;
+ MqttDisconnectReasonCode _disconnectReason;
public MqttClientConnection(MqttConnectPacket connectPacket,
IMqttChannelAdapter channelAdapter,
@@ -70,9 +71,9 @@ namespace MQTTnet.Server
_lastNonKeepAlivePacketReceivedTimestamp = LastPacketReceivedTimestamp;
}
- public MqttConnectPacket ConnectPacket { get; }
+ public MqttClientConnectionStatus Status { get; private set; } = MqttClientConnectionStatus.Initializing;
- public bool IsTakeOver { get; set; }
+ public MqttConnectPacket ConnectPacket { get; }
public string ClientId => ConnectPacket.ClientId;
@@ -82,9 +83,12 @@ namespace MQTTnet.Server
public MqttClientSession Session { get; }
- public async Task StopAsync()
+ public async Task StopAsync(MqttDisconnectReasonCode reason)
{
- if (IsTakeOver)
+ Status = MqttClientConnectionStatus.Finalizing;
+ _disconnectReason = reason;
+
+ if (reason == MqttDisconnectReasonCode.SessionTakenOver || reason == MqttDisconnectReasonCode.KeepAliveTimeout)
{
// Is is very important to send the DISCONNECT packet here BEFORE cancelling the
// token because the entire connection is closed (disposed) as soon as the cancellation
@@ -94,7 +98,7 @@ namespace MQTTnet.Server
{
await _channelAdapter.SendPacketAsync(new MqttDisconnectPacket
{
- ReasonCode = MqttDisconnectReasonCode.SessionTakenOver
+ ReasonCode = reason
}, _serverOptions.DefaultCommunicationTimeout, CancellationToken.None).ConfigureAwait(false);
}
catch (Exception exception)
@@ -161,6 +165,8 @@ namespace MQTTnet.Server
while (!cancellationToken.IsCancellationRequested)
{
+ Status = MqttClientConnectionStatus.Running;
+
var packet = await _channelAdapter.ReceivePacketAsync(TimeSpan.Zero, cancellationToken).ConfigureAwait(false);
if (packet == null)
{
@@ -242,7 +248,7 @@ namespace MQTTnet.Server
}
finally
{
- if (IsTakeOver)
+ if (_disconnectReason == MqttDisconnectReasonCode.SessionTakenOver)
{
disconnectType = MqttClientDisconnectType.Takeover;
}
diff --git a/Source/MQTTnet/Server/MqttClientConnectionStatus.cs b/Source/MQTTnet/Server/MqttClientConnectionStatus.cs
new file mode 100644
index 00000000..8a132b0a
--- /dev/null
+++ b/Source/MQTTnet/Server/MqttClientConnectionStatus.cs
@@ -0,0 +1,11 @@
+namespace MQTTnet.Server
+{
+ public enum MqttClientConnectionStatus
+ {
+ Initializing,
+
+ Running,
+
+ Finalizing
+ }
+}
\ No newline at end of file
diff --git a/Source/MQTTnet/Server/MqttClientSessionsManager.cs b/Source/MQTTnet/Server/MqttClientSessionsManager.cs
index 3e6d95f0..5cad56f3 100644
--- a/Source/MQTTnet/Server/MqttClientSessionsManager.cs
+++ b/Source/MQTTnet/Server/MqttClientSessionsManager.cs
@@ -25,7 +25,6 @@ namespace MQTTnet.Server
readonly IDictionary