mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-18 18:43:10 +08:00
Refactor subscribe and unsubscribe to support MQTTv5.
This commit is contained in:
@@ -52,7 +52,7 @@ namespace MQTTnet.Benchmarks
|
||||
{
|
||||
channel.Reset();
|
||||
|
||||
var header = reader.ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult();
|
||||
var header = reader.ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
|
||||
|
||||
var receivedPacket = new ReceivedMqttPacket(
|
||||
header.Flags,
|
||||
|
||||
@@ -13,26 +13,32 @@ namespace MQTTnet.Tests
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var managedClient = factory.CreateManagedMqttClient();
|
||||
try
|
||||
{
|
||||
var clientOptions = new ManagedMqttClientOptionsBuilder()
|
||||
.WithMaxPendingMessages(5)
|
||||
.WithPendingMessagesOverflowStrategy(MqttPendingMessagesOverflowStrategy.DropNewMessage);
|
||||
|
||||
var clientOptions = new ManagedMqttClientOptionsBuilder()
|
||||
.WithMaxPendingMessages(5)
|
||||
.WithPendingMessagesOverflowStrategy(MqttPendingMessagesOverflowStrategy.DropNewMessage);
|
||||
clientOptions.WithClientOptions(o => o.WithTcpServer("localhost"));
|
||||
|
||||
clientOptions.WithClientOptions(o => o.WithTcpServer("localhost"));
|
||||
await managedClient.StartAsync(clientOptions.Build());
|
||||
|
||||
await managedClient.StartAsync(clientOptions.Build());
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "1" });
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "2" });
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "3" });
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "4" });
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "5" });
|
||||
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "1" });
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "2" });
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "3" });
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "4" });
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "5" });
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "6" });
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "7" });
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "8" });
|
||||
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "6" });
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "7" });
|
||||
await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "8" });
|
||||
|
||||
Assert.AreEqual(5, managedClient.PendingApplicationMessagesCount);
|
||||
Assert.AreEqual(5, managedClient.PendingApplicationMessagesCount);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await managedClient.StopAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,14 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Client.Options;
|
||||
using MQTTnet.Client.Receiving;
|
||||
using MQTTnet.Exceptions;
|
||||
using MQTTnet.Protocol;
|
||||
using MQTTnet.Server;
|
||||
|
||||
namespace MQTTnet.Tests
|
||||
@@ -39,11 +42,100 @@ namespace MQTTnet.Tests
|
||||
Assert.IsInstanceOfType(ex.InnerException, typeof(SocketException));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Client_Preserve_Message_Order()
|
||||
{
|
||||
// The messages are sent in reverse or to ensure that the delay in the handler
|
||||
// needs longer for the first messages and later messages may be processed earlier (if there
|
||||
// is an issue).
|
||||
const int MessagesCount = 50;
|
||||
|
||||
using (var testSetup = new TestSetup())
|
||||
{
|
||||
await testSetup.StartServerAsync();
|
||||
|
||||
var client1 = await testSetup.ConnectClientAsync();
|
||||
await client1.SubscribeAsync("x");
|
||||
|
||||
var receivedValues = new List<int>();
|
||||
|
||||
async Task Handler1(MqttApplicationMessageHandlerContext context)
|
||||
{
|
||||
var value = int.Parse(context.ApplicationMessage.ConvertPayloadToString());
|
||||
await Task.Delay(value);
|
||||
|
||||
lock (receivedValues)
|
||||
{
|
||||
receivedValues.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
client1.UseReceivedApplicationMessageHandler(Handler1);
|
||||
|
||||
var client2 = await testSetup.ConnectClientAsync();
|
||||
for (var i = MessagesCount; i > 0; i--)
|
||||
{
|
||||
await client2.PublishAsync("x", i.ToString());
|
||||
}
|
||||
|
||||
await Task.Delay(5000);
|
||||
|
||||
for (var i = MessagesCount; i > 0; i--)
|
||||
{
|
||||
Assert.AreEqual(i, receivedValues[MessagesCount - i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Client_Send_Reply_For_Any_Received_Message()
|
||||
{
|
||||
using (var testSetup = new TestSetup())
|
||||
{
|
||||
await testSetup.StartServerAsync();
|
||||
|
||||
var client1 = await testSetup.ConnectClientAsync();
|
||||
await client1.SubscribeAsync("request/+");
|
||||
|
||||
async Task Handler1(MqttApplicationMessageHandlerContext context)
|
||||
{
|
||||
await client1.PublishAsync($"reply/{context.ApplicationMessage.Topic}");
|
||||
}
|
||||
|
||||
client1.UseReceivedApplicationMessageHandler(Handler1);
|
||||
|
||||
var client2 = await testSetup.ConnectClientAsync();
|
||||
await client2.SubscribeAsync("reply/#");
|
||||
|
||||
var replies = new List<string>();
|
||||
|
||||
void Handler2(MqttApplicationMessageHandlerContext context)
|
||||
{
|
||||
lock (replies)
|
||||
{
|
||||
replies.Add(context.ApplicationMessage.Topic);
|
||||
}
|
||||
}
|
||||
|
||||
client2.UseReceivedApplicationMessageHandler((Action<MqttApplicationMessageHandlerContext>) Handler2);
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
await client2.PublishAsync("request/a");
|
||||
await client2.PublishAsync("request/b");
|
||||
await client2.PublishAsync("request/c");
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
Assert.AreEqual("reply/request/a,reply/request/b,reply/request/c", string.Join("," , replies));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Client_Publish()
|
||||
{
|
||||
var server = new MqttFactory().CreateMqttServer();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
var receivedMessages = new List<MqttApplicationMessage>();
|
||||
@@ -125,39 +217,85 @@ namespace MQTTnet.Tests
|
||||
}
|
||||
}
|
||||
|
||||
//#if DEBUG
|
||||
// [TestMethod]
|
||||
// public async Task Client_Cleanup_On_Authentification_Fails()
|
||||
// {
|
||||
// var channel = new TestMqttCommunicationAdapter();
|
||||
// var channel2 = new TestMqttCommunicationAdapter();
|
||||
// channel.Partner = channel2;
|
||||
// channel2.Partner = channel;
|
||||
[TestMethod]
|
||||
public async Task Client_Exception_In_Application_Message_Handler()
|
||||
{
|
||||
using (var testSetup = new TestSetup())
|
||||
{
|
||||
testSetup.IgnoreClientLogErrors = true;
|
||||
testSetup.IgnoreServerLogErrors = true;
|
||||
|
||||
// Task.Run(async () => {
|
||||
// var connect = await channel2.ReceivePacketAsync(TimeSpan.Zero, CancellationToken.None);
|
||||
// await channel2.SendPacketAsync(new MqttConnAckPacket
|
||||
// {
|
||||
// ConnectReturnCode = Protocol.MqttConnectReturnCode.ConnectionRefusedNotAuthorized
|
||||
// }, CancellationToken.None);
|
||||
// });
|
||||
|
||||
// var fake = new TestMqttCommunicationAdapterFactory(channel);
|
||||
await testSetup.StartServerAsync(
|
||||
new MqttServerOptionsBuilder()
|
||||
.WithPersistentSessions()
|
||||
.WithDefaultCommunicationTimeout(TimeSpan.FromMilliseconds(50)));
|
||||
|
||||
// var client = new MqttClient(fake, new MqttNetLogger());
|
||||
var client1 = await testSetup.ConnectClientAsync(new MqttClientOptionsBuilder()
|
||||
.WithCleanSession(false));
|
||||
|
||||
// try
|
||||
// {
|
||||
// await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("any-server").Build());
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Assert.IsInstanceOfType(ex, typeof(MqttConnectingFailedException));
|
||||
// }
|
||||
await client1.SubscribeAsync("x", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
// Assert.IsTrue(client._packetReceiverTask == null || client._packetReceiverTask.IsCompleted, "receive loop not completed");
|
||||
// Assert.IsTrue(client._keepAliveMessageSenderTask == null || client._keepAliveMessageSenderTask.IsCompleted, "keepalive loop not completed");
|
||||
// }
|
||||
//#endif
|
||||
var retries = 0;
|
||||
|
||||
async Task Handler1(MqttApplicationMessageHandlerContext context)
|
||||
{
|
||||
retries++;
|
||||
|
||||
await Task.Delay(50);
|
||||
throw new Exception("Broken!");
|
||||
}
|
||||
|
||||
client1.UseReceivedApplicationMessageHandler(Handler1);
|
||||
|
||||
var client2 = await testSetup.ConnectClientAsync();
|
||||
await client2.PublishAsync("x");
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
// The server should disconnect clients which are not responding.
|
||||
Assert.IsFalse(client1.IsConnected);
|
||||
|
||||
await client1.ReconnectAsync().ConfigureAwait(false);
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
Assert.AreEqual(2, retries);
|
||||
}
|
||||
}
|
||||
|
||||
//#if DEBUG
|
||||
// [TestMethod]
|
||||
// public async Task Client_Cleanup_On_Authentification_Fails()
|
||||
// {
|
||||
// var channel = new TestMqttCommunicationAdapter();
|
||||
// var channel2 = new TestMqttCommunicationAdapter();
|
||||
// channel.Partner = channel2;
|
||||
// channel2.Partner = channel;
|
||||
|
||||
// Task.Run(async () => {
|
||||
// var connect = await channel2.ReceivePacketAsync(TimeSpan.Zero, CancellationToken.None);
|
||||
// await channel2.SendPacketAsync(new MqttConnAckPacket
|
||||
// {
|
||||
// ConnectReturnCode = Protocol.MqttConnectReturnCode.ConnectionRefusedNotAuthorized
|
||||
// }, CancellationToken.None);
|
||||
// });
|
||||
|
||||
// var fake = new TestMqttCommunicationAdapterFactory(channel);
|
||||
|
||||
// var client = new MqttClient(fake, new MqttNetLogger());
|
||||
|
||||
// try
|
||||
// {
|
||||
// await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("any-server").Build());
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Assert.IsInstanceOfType(ex, typeof(MqttConnectingFailedException));
|
||||
// }
|
||||
|
||||
// Assert.IsTrue(client._packetReceiverTask == null || client._packetReceiverTask.IsCompleted, "receive loop not completed");
|
||||
// Assert.IsTrue(client._keepAliveMessageSenderTask == null || client._keepAliveMessageSenderTask.IsCompleted, "keepalive loop not completed");
|
||||
// }
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,10 @@ namespace MQTTnet.Tests
|
||||
public void Reset()
|
||||
{
|
||||
var p = new MqttPacketIdentifierProvider();
|
||||
Assert.AreEqual(1, p.GetNewPacketIdentifier());
|
||||
Assert.AreEqual(2, p.GetNewPacketIdentifier());
|
||||
Assert.AreEqual(1, p.GetNextPacketIdentifier());
|
||||
Assert.AreEqual(2, p.GetNextPacketIdentifier());
|
||||
p.Reset();
|
||||
Assert.AreEqual(1, p.GetNewPacketIdentifier());
|
||||
Assert.AreEqual(1, p.GetNextPacketIdentifier());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -23,10 +23,10 @@ namespace MQTTnet.Tests
|
||||
|
||||
for (ushort i = 0; i < ushort.MaxValue; i++)
|
||||
{
|
||||
Assert.AreEqual(i + 1, p.GetNewPacketIdentifier());
|
||||
Assert.AreEqual(i + 1, p.GetNextPacketIdentifier());
|
||||
}
|
||||
|
||||
Assert.AreEqual(1, p.GetNewPacketIdentifier());
|
||||
Assert.AreEqual(1, p.GetNextPacketIdentifier());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Exceptions;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Internal;
|
||||
|
||||
@@ -11,12 +11,13 @@ namespace MQTTnet.Tests
|
||||
public class MqttPacketReaderTests
|
||||
{
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(MqttCommunicationClosedGracefullyException))]
|
||||
public void MqttPacketReader_EmptyStream()
|
||||
public async Task MqttPacketReader_EmptyStream()
|
||||
{
|
||||
var fixedHeader = new byte[2];
|
||||
var reader = new MqttPacketReader(new TestMqttChannel(new MemoryStream()));
|
||||
reader.ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult();
|
||||
var readResult = await reader.ReadFixedHeaderAsync(fixedHeader, CancellationToken.None);
|
||||
|
||||
Assert.IsTrue(readResult.ConnectionClosed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ namespace MQTTnet.Tests
|
||||
|
||||
var header = new MqttPacketReader(testChannel).ReadFixedHeaderAsync(
|
||||
new byte[2],
|
||||
CancellationToken.None).GetAwaiter().GetResult();
|
||||
CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
|
||||
|
||||
var eof = buffer.Offset + buffer.Count;
|
||||
|
||||
@@ -550,7 +550,7 @@ namespace MQTTnet.Tests
|
||||
{
|
||||
var channel = new TestMqttChannel(headerStream);
|
||||
var fixedHeader = new byte[2];
|
||||
var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult();
|
||||
var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
|
||||
|
||||
using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, header.RemainingLength))
|
||||
{
|
||||
@@ -586,7 +586,7 @@ namespace MQTTnet.Tests
|
||||
var channel = new TestMqttChannel(headerStream);
|
||||
var fixedHeader = new byte[2];
|
||||
|
||||
var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult();
|
||||
var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
|
||||
|
||||
using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, (int)header.RemainingLength))
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
@@ -19,36 +20,36 @@ namespace MQTTnet.Tests
|
||||
public class MqttServerTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void MqttServer_PublishSimple_AtMostOnce()
|
||||
public async Task MqttServer_PublishSimple_AtMostOnce()
|
||||
{
|
||||
TestPublishAsync(
|
||||
await TestPublishAsync(
|
||||
"A/B/C",
|
||||
MqttQualityOfServiceLevel.AtMostOnce,
|
||||
"A/B/C",
|
||||
MqttQualityOfServiceLevel.AtMostOnce,
|
||||
1).Wait();
|
||||
1);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MqttServer_PublishSimple_AtLeastOnce()
|
||||
public async Task MqttServer_PublishSimple_AtLeastOnce()
|
||||
{
|
||||
TestPublishAsync(
|
||||
await TestPublishAsync(
|
||||
"A/B/C",
|
||||
MqttQualityOfServiceLevel.AtLeastOnce,
|
||||
"A/B/C",
|
||||
MqttQualityOfServiceLevel.AtLeastOnce,
|
||||
1).Wait();
|
||||
1);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MqttServer_PublishSimple_ExactlyOnce()
|
||||
public async Task MqttServer_PublishSimple_ExactlyOnce()
|
||||
{
|
||||
TestPublishAsync(
|
||||
await TestPublishAsync(
|
||||
"A/B/C",
|
||||
MqttQualityOfServiceLevel.ExactlyOnce,
|
||||
"A/B/C",
|
||||
MqttQualityOfServiceLevel.ExactlyOnce,
|
||||
1).Wait();
|
||||
1);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -143,32 +144,27 @@ namespace MQTTnet.Tests
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task MqttServer_Publish()
|
||||
public async Task MqttServer_Publish_From_Server()
|
||||
{
|
||||
var serverAdapter = new TestMqttServerAdapter();
|
||||
var s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
|
||||
var receivedMessagesCount = 0;
|
||||
|
||||
try
|
||||
using (var testSetup = new TestSetup())
|
||||
{
|
||||
await s.StartAsync(new MqttServerOptions());
|
||||
var server = await testSetup.StartServerAsync();
|
||||
|
||||
var c1 = await serverAdapter.ConnectTestClient("c1");
|
||||
var receivedMessagesCount = 0;
|
||||
|
||||
c1.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
|
||||
var client = await testSetup.ConnectClientAsync();
|
||||
client.UseReceivedApplicationMessageHandler(c => Interlocked.Increment(ref receivedMessagesCount));
|
||||
|
||||
var message = new MqttApplicationMessageBuilder().WithTopic("a").WithAtLeastOnceQoS().Build();
|
||||
await c1.SubscribeAsync(new TopicFilter { Topic = "a", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce });
|
||||
await client.SubscribeAsync(new TopicFilter { Topic = "a", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce });
|
||||
|
||||
await s.PublishAsync(message);
|
||||
await Task.Delay(500);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await s.StopAsync();
|
||||
}
|
||||
await server.PublishAsync(message);
|
||||
|
||||
Assert.AreEqual(1, receivedMessagesCount);
|
||||
await Task.Delay(1000);
|
||||
await server.StopAsync();
|
||||
|
||||
Assert.AreEqual(1, receivedMessagesCount);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -438,40 +434,43 @@ namespace MQTTnet.Tests
|
||||
[TestMethod]
|
||||
public async Task MqttServer_Lots_Of_Retained_Messages()
|
||||
{
|
||||
const int ClientCount = 100;
|
||||
const int ClientCount = 25;
|
||||
|
||||
var server = new MqttFactory().CreateMqttServer();
|
||||
try
|
||||
using (var testSetup = new TestSetup())
|
||||
{
|
||||
await server.StartAsync(new MqttServerOptionsBuilder().Build());
|
||||
|
||||
Parallel.For(
|
||||
0,
|
||||
ClientCount,
|
||||
new ParallelOptions { MaxDegreeOfParallelism = 10 },
|
||||
i =>
|
||||
var server = await testSetup.StartServerAsync();
|
||||
|
||||
var tasks = new ConcurrentBag<Task>();
|
||||
for (var i = 0; i < ClientCount; i++)
|
||||
{
|
||||
using (var client = new MqttFactory().CreateMqttClient())
|
||||
var clientId = i;
|
||||
tasks.Add(Task.Run(async () =>
|
||||
{
|
||||
client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("localhost").Build())
|
||||
.GetAwaiter().GetResult();
|
||||
|
||||
for (var j = 0; j < 10; j++)
|
||||
try
|
||||
{
|
||||
// Clear retained message.
|
||||
client.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("r" + i)
|
||||
.WithPayload(new byte[0]).WithRetainFlag().Build()).GetAwaiter().GetResult();
|
||||
using (var client = await testSetup.ConnectClientAsync())
|
||||
{
|
||||
// Clear retained message.
|
||||
await client.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("r" + clientId)
|
||||
.WithPayload(new byte[0]).WithRetainFlag().Build());
|
||||
|
||||
// Set retained message.
|
||||
client.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("r" + i)
|
||||
.WithPayload("value" + j).WithRetainFlag().Build()).GetAwaiter().GetResult();
|
||||
// Set retained message.
|
||||
await client.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("r" + clientId)
|
||||
.WithPayload("value").WithRetainFlag().Build());
|
||||
|
||||
await Task.Delay(10);
|
||||
|
||||
await client.DisconnectAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
testSetup.TrackException(exception);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
Thread.Sleep(100);
|
||||
|
||||
client.DisconnectAsync().GetAwaiter().GetResult();
|
||||
}
|
||||
});
|
||||
await Task.WhenAll(tasks.ToArray());
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
@@ -484,10 +483,6 @@ namespace MQTTnet.Tests
|
||||
Assert.IsTrue(retainedMessages.Any(m => m.Topic == "r" + i));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
await server.StopAsync();
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -986,6 +981,23 @@ namespace MQTTnet.Tests
|
||||
MqttQualityOfServiceLevel filterQualityOfServiceLevel,
|
||||
int expectedReceivedMessagesCount)
|
||||
{
|
||||
//using (var testSetup = new TestSetup())
|
||||
//{
|
||||
// var server = await testSetup.StartServerAsync(new MqttServerOptionsBuilder());
|
||||
|
||||
// var clientOptions = new MqttClientOptionsBuilder();
|
||||
// var c1 = await testSetup.ConnectClientAsync(clientOptions);
|
||||
// await Task.Delay(500);
|
||||
// Assert.AreEqual(1, (await server.GetClientSessionsStatusAsync()).Count);
|
||||
|
||||
// await c1.DisconnectAsync();
|
||||
// await Task.Delay(500);
|
||||
|
||||
// Assert.AreEqual(0, (await server.GetClientSessionsStatusAsync()).Count);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
var s = new MqttFactory().CreateMqttServer();
|
||||
|
||||
var receivedMessagesCount = 0;
|
||||
@@ -994,13 +1006,15 @@ namespace MQTTnet.Tests
|
||||
await s.StartAsync(new MqttServerOptions());
|
||||
|
||||
var c1 = new MqttFactory().CreateMqttClient();
|
||||
c1.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
|
||||
await c1.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("localhost").Build());
|
||||
c1.UseReceivedApplicationMessageHandler(c => receivedMessagesCount++);
|
||||
|
||||
await c1.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build());
|
||||
await c1.SubscribeAsync(new TopicFilterBuilder().WithTopic(topicFilter).WithQualityOfServiceLevel(filterQualityOfServiceLevel).Build());
|
||||
|
||||
var c2 = new MqttFactory().CreateMqttClient();
|
||||
await c2.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("localhost").Build());
|
||||
await c2.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build());
|
||||
await c2.PublishAsync(builder => builder.WithTopic(topic).WithPayload(new byte[0]).WithQualityOfServiceLevel(qualityOfServiceLevel));
|
||||
await c2.DisconnectAsync().ConfigureAwait(false);
|
||||
|
||||
await Task.Delay(500);
|
||||
await c1.UnsubscribeAsync(topicFilter);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Client.Options;
|
||||
@@ -16,10 +16,15 @@ namespace MQTTnet.Tests
|
||||
private readonly IMqttNetLogger _serverLogger = new MqttNetLogger("server");
|
||||
private readonly IMqttNetLogger _clientLogger = new MqttNetLogger("client");
|
||||
|
||||
private readonly List<string> _serverErrors = new List<string>();
|
||||
private readonly List<string> _clientErrors = new List<string>();
|
||||
|
||||
private readonly List<Exception> _exceptions = new List<Exception>();
|
||||
|
||||
private IMqttServer _server;
|
||||
|
||||
private long _serverErrorsCount;
|
||||
private long _clientErrorsCount;
|
||||
public bool IgnoreClientLogErrors { get; set; }
|
||||
public bool IgnoreServerLogErrors { get; set; }
|
||||
|
||||
public TestSetup()
|
||||
{
|
||||
@@ -27,19 +32,30 @@ namespace MQTTnet.Tests
|
||||
{
|
||||
if (e.TraceMessage.Level == MqttNetLogLevel.Error)
|
||||
{
|
||||
Interlocked.Increment(ref _serverErrorsCount);
|
||||
lock (_serverErrors)
|
||||
{
|
||||
_serverErrors.Add(e.TraceMessage.ToString());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_clientLogger.LogMessagePublished += (s, e) =>
|
||||
{
|
||||
if (e.TraceMessage.Level == MqttNetLogLevel.Error)
|
||||
lock (_clientErrors)
|
||||
{
|
||||
Interlocked.Increment(ref _clientErrorsCount);
|
||||
if (e.TraceMessage.Level == MqttNetLogLevel.Error)
|
||||
{
|
||||
_clientErrors.Add(e.TraceMessage.ToString());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Task<IMqttServer> StartServerAsync()
|
||||
{
|
||||
return StartServerAsync(new MqttServerOptionsBuilder());
|
||||
}
|
||||
|
||||
public async Task<IMqttServer> StartServerAsync(MqttServerOptionsBuilder options)
|
||||
{
|
||||
if (_server != null)
|
||||
@@ -53,40 +69,63 @@ namespace MQTTnet.Tests
|
||||
return _server;
|
||||
}
|
||||
|
||||
public Task<IMqttClient> ConnectClientAsync()
|
||||
{
|
||||
return ConnectClientAsync(new MqttClientOptionsBuilder());
|
||||
}
|
||||
|
||||
public async Task<IMqttClient> ConnectClientAsync(MqttClientOptionsBuilder options)
|
||||
{
|
||||
var client = _mqttFactory.CreateMqttClient(_clientLogger);
|
||||
_clients.Add(client);
|
||||
|
||||
await client.ConnectAsync(options.WithTcpServer("localhost", 1888).Build());
|
||||
|
||||
_clients.Add(client);
|
||||
return client;
|
||||
}
|
||||
|
||||
public void ThrowIfLogErrors()
|
||||
{
|
||||
if (_serverErrorsCount > 0)
|
||||
lock (_serverErrors)
|
||||
{
|
||||
throw new Exception($"Server had {_serverErrorsCount} errors.");
|
||||
if (!IgnoreServerLogErrors && _serverErrors.Count > 0)
|
||||
{
|
||||
throw new Exception($"Server had {_serverErrors.Count} errors (${string.Join(Environment.NewLine, _serverErrors)}).");
|
||||
}
|
||||
}
|
||||
|
||||
if (_clientErrorsCount > 0)
|
||||
lock (_clientErrors)
|
||||
{
|
||||
throw new Exception($"Client(s) had {_clientErrorsCount} errors.");
|
||||
if (!IgnoreClientLogErrors && _clientErrors.Count > 0)
|
||||
{
|
||||
throw new Exception($"Client(s) had {_clientErrors.Count} errors (${string.Join(Environment.NewLine, _clientErrors)}).");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ThrowIfLogErrors();
|
||||
|
||||
foreach (var mqttClient in _clients)
|
||||
{
|
||||
mqttClient.DisconnectAsync().GetAwaiter().GetResult();
|
||||
mqttClient.Dispose();
|
||||
mqttClient?.DisconnectAsync().GetAwaiter().GetResult();
|
||||
mqttClient?.Dispose();
|
||||
}
|
||||
|
||||
_server.StopAsync().GetAwaiter().GetResult();
|
||||
|
||||
ThrowIfLogErrors();
|
||||
|
||||
if (_exceptions.Any())
|
||||
{
|
||||
throw new Exception($"{_exceptions.Count} exceptions tracked.");
|
||||
}
|
||||
}
|
||||
|
||||
public void TrackException(Exception exception)
|
||||
{
|
||||
lock (_exceptions)
|
||||
{
|
||||
_exceptions.Add(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user