mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-22 04:43:04 +08:00
Send DISCONNECT packets to MQTT5 clients only (#1506)
This commit is contained in:
@@ -175,6 +175,49 @@ namespace MQTTnet.Tests.MQTTv5
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task Disconnect_with_Reason()
|
||||||
|
{
|
||||||
|
using (var testEnvironment = CreateTestEnvironment())
|
||||||
|
{
|
||||||
|
var disconnectReason = MQTTnet.Client.MqttClientDisconnectReason.UnspecifiedError;
|
||||||
|
|
||||||
|
string testClientId = null;
|
||||||
|
|
||||||
|
await testEnvironment.StartServer();
|
||||||
|
|
||||||
|
testEnvironment.Server.ClientConnectedAsync += e =>
|
||||||
|
{
|
||||||
|
testClientId = e.ClientId;
|
||||||
|
return PlatformAbstractionLayer.CompletedTask;
|
||||||
|
};
|
||||||
|
|
||||||
|
var client = await testEnvironment.ConnectClient(new MQTTnet.Client.MqttClientOptionsBuilder().WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V500));
|
||||||
|
|
||||||
|
client.DisconnectedAsync += e =>
|
||||||
|
{
|
||||||
|
disconnectReason = e.Reason;
|
||||||
|
return PlatformAbstractionLayer.CompletedTask;
|
||||||
|
};
|
||||||
|
|
||||||
|
await LongTestDelay();
|
||||||
|
|
||||||
|
// Test client should be connected now
|
||||||
|
|
||||||
|
Assert.IsTrue(testClientId != null);
|
||||||
|
|
||||||
|
// Have the server disconnect the client with AdministrativeAction reason
|
||||||
|
|
||||||
|
await testEnvironment.Server.DisconnectClientAsync(testClientId, Protocol.MqttDisconnectReasonCode.AdministrativeAction);
|
||||||
|
|
||||||
|
await LongTestDelay();
|
||||||
|
|
||||||
|
// The reason should be returned to the client in the DISCONNECT packet
|
||||||
|
|
||||||
|
Assert.AreEqual(MQTTnet.Client.MqttClientDisconnectReason.AdministrativeAction, disconnectReason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MqttClientOptions CreateClientOptions(TestEnvironment testEnvironment, string clientId, bool cleanSession, uint sessionExpiryInterval)
|
MqttClientOptions CreateClientOptions(TestEnvironment testEnvironment, string clientId, bool cleanSession, uint sessionExpiryInterval)
|
||||||
{
|
{
|
||||||
return testEnvironment.Factory.CreateClientOptionsBuilder()
|
return testEnvironment.Factory.CreateClientOptionsBuilder()
|
||||||
|
|||||||
@@ -935,7 +935,62 @@ namespace MQTTnet.Tests.Server
|
|||||||
Assert.IsTrue(client.IsConnected);
|
Assert.IsTrue(client.IsConnected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task Disconnect_Client_with_Reason()
|
||||||
|
{
|
||||||
|
using (var testEnvironment = CreateTestEnvironment())
|
||||||
|
{
|
||||||
|
var disconnectPacketReceived = false;
|
||||||
|
|
||||||
|
string testClientId = null;
|
||||||
|
|
||||||
|
await testEnvironment.StartServer();
|
||||||
|
|
||||||
|
testEnvironment.Server.ClientConnectedAsync += e =>
|
||||||
|
{
|
||||||
|
testClientId = e.ClientId;
|
||||||
|
return PlatformAbstractionLayer.CompletedTask;
|
||||||
|
};
|
||||||
|
|
||||||
|
var client = testEnvironment.CreateClient();
|
||||||
|
|
||||||
|
client.InspectPackage += e =>
|
||||||
|
{
|
||||||
|
if (e.Buffer.Length > 0)
|
||||||
|
{
|
||||||
|
if (e.Buffer[0] == (byte)Protocol.MqttControlPacketType.Disconnect << 4)
|
||||||
|
{
|
||||||
|
disconnectPacketReceived = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PlatformAbstractionLayer.CompletedTask;
|
||||||
|
};
|
||||||
|
|
||||||
|
await client.ConnectAsync(
|
||||||
|
new MqttClientOptionsBuilder().WithTcpServer("localhost", testEnvironment.ServerPort)
|
||||||
|
.WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V311)
|
||||||
|
.Build()
|
||||||
|
);
|
||||||
|
|
||||||
|
await LongTestDelay();
|
||||||
|
|
||||||
|
// Test client should be connected now
|
||||||
|
|
||||||
|
Assert.IsTrue(testClientId != null);
|
||||||
|
|
||||||
|
// Have the server disconnect the client with SessionTakenOver reason; no DISCONNECT should be sent to MQTT 3.1.1 clients
|
||||||
|
|
||||||
|
await testEnvironment.Server.DisconnectClientAsync(testClientId, Protocol.MqttDisconnectReasonCode.SessionTakenOver);
|
||||||
|
|
||||||
|
await LongTestDelay();
|
||||||
|
|
||||||
|
// MQTT 3.1.1 client should not receive a disconnect packet
|
||||||
|
|
||||||
|
Assert.IsFalse(disconnectPacketReceived, "Disconnect packet received when none is expected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ConnectionValidationHandler(ValidatingConnectionEventArgs eventArgs)
|
void ConnectionValidationHandler(ValidatingConnectionEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (_connected.ContainsKey(eventArgs.ClientId))
|
if (_connected.ContainsKey(eventArgs.ClientId))
|
||||||
|
|||||||
@@ -147,7 +147,9 @@ namespace MQTTnet.Server
|
|||||||
{
|
{
|
||||||
IsRunning = false;
|
IsRunning = false;
|
||||||
|
|
||||||
if (reason == MqttDisconnectReasonCode.SessionTakenOver || reason == MqttDisconnectReasonCode.KeepAliveTimeout)
|
// Potentially send disconnect reason to MQTT 5 clients
|
||||||
|
|
||||||
|
if (ChannelAdapter.PacketFormatterAdapter.ProtocolVersion == MqttProtocolVersion.V500 && reason != MqttDisconnectReasonCode.NormalDisconnection)
|
||||||
{
|
{
|
||||||
// Is is very important to send the DISCONNECT packet here BEFORE cancelling the
|
// 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
|
// token because the entire connection is closed (disposed) as soon as the cancellation
|
||||||
|
|||||||
Reference in New Issue
Block a user