Fix MQTT 3.1.1 session persistence when CleanSession=1 (#1294)

This commit is contained in:
logicaloud
2021-11-13 10:05:54 +01:00
committed by GitHub
parent 47cd5aa3cd
commit f0ea13c07f
6 changed files with 107 additions and 17 deletions
+2 -2
View File
@@ -1167,7 +1167,7 @@ namespace MQTTnet.Tests.Server
var server = await testEnvironment.StartServer(new MqttServerOptionsBuilder().WithPersistentSessions());
// Create the session including the subscription.
var client1 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("a"));
var client1 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("a").WithCleanSession(false));
await client1.SubscribeAsync("x");
await client1.DisconnectAsync();
await Task.Delay(500);
@@ -1175,7 +1175,7 @@ namespace MQTTnet.Tests.Server
var clientStatus = await server.GetClientStatusAsync();
Assert.AreEqual(0, clientStatus.Count);
var client2 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("b"));
var client2 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("b").WithCleanSession(false));
await client2.PublishAsync("x", "1");
await client2.PublishAsync("x", "2");
await client2.PublishAsync("x", "3");
@@ -1,4 +1,4 @@
using System.Collections.Concurrent;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MQTTnet.Packets;
@@ -107,7 +107,8 @@ namespace MQTTnet.Tests.Server
new ConcurrentDictionary<object, object>(),
new MqttServerEventDispatcher(new TestLogger()),
new MqttServerOptions(),
new MqttRetainedMessagesManager());
new MqttRetainedMessagesManager(),
false);
}
}
}
@@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -107,6 +107,58 @@ namespace MQTTnet.Tests.Server
}
}
[TestMethod]
public async Task Clean_Session_Persistence()
{
using (var testEnvironment = new TestEnvironment(TestContext))
{
// Create server with persistent sessions enabled
await testEnvironment.StartServer(o => o.WithPersistentSessions());
const string ClientId = "Client1";
// Create client with clean session and long session expiry interval
var client1 = await testEnvironment.ConnectClient(o => o
.WithProtocolVersion(Formatter.MqttProtocolVersion.V311)
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
.WithSessionExpiryInterval(9999) // not relevant for v311 but testing impact
.WithCleanSession(true) // start and end with clean session
.WithClientId(ClientId)
.Build()
);
// Disconnect; empty session should be removed from server
await client1.DisconnectAsync();
// Simulate some time delay between connections
await Task.Delay(1000);
// Reconnect the same client ID without clean session
var client2 = testEnvironment.CreateClient();
var options = testEnvironment.Factory.CreateClientOptionsBuilder()
.WithProtocolVersion(Formatter.MqttProtocolVersion.V311)
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
.WithSessionExpiryInterval(9999) // not relevant for v311 but testing impact
.WithCleanSession(false) // see if there is a session
.WithClientId(ClientId)
.Build();
var result = await client2.ConnectAsync(options).ConfigureAwait(false);
await client2.DisconnectAsync();
// Session should NOT be present for MQTT v311 and initial CleanSession == true
Assert.IsTrue(!result.IsSessionPresent, "Session present");
}
}
async Task<IMqttClient> TryConnect(TestEnvironment testEnvironment, MqttClientOptionsBuilder options)
{
try
@@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MQTTnet.Client;
@@ -81,8 +81,8 @@ namespace MQTTnet.Tests.Server
{
var server = await testEnvironment.StartServer(new MqttServerOptionsBuilder().WithPersistentSessions());
var c1 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("client1"));
var c2 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("client2"));
var c1 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("client1").WithCleanSession(false));
var c2 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("client2").WithCleanSession(false));
await c1.DisconnectAsync();