diff --git a/Frameworks/MQTTnet.AspnetCore/MQTTnet.AspnetCore.csproj b/Frameworks/MQTTnet.AspnetCore/MQTTnet.AspnetCore.csproj
index 5556b11c..fbde3f2b 100644
--- a/Frameworks/MQTTnet.AspnetCore/MQTTnet.AspnetCore.csproj
+++ b/Frameworks/MQTTnet.AspnetCore/MQTTnet.AspnetCore.csproj
@@ -6,6 +6,10 @@
2.5.2.0
+
+ RELEASE;NETSTANDARD2_0
+
+
diff --git a/Frameworks/MQTTnet.NetStandard/Adapter/MqttChannelAdapter.cs b/Frameworks/MQTTnet.NetStandard/Adapter/MqttChannelAdapter.cs
index bf89fabf..2a9815d4 100644
--- a/Frameworks/MQTTnet.NetStandard/Adapter/MqttChannelAdapter.cs
+++ b/Frameworks/MQTTnet.NetStandard/Adapter/MqttChannelAdapter.cs
@@ -31,23 +31,23 @@ namespace MQTTnet.Adapter
public IMqttPacketSerializer PacketSerializer { get; }
- public async Task ConnectAsync(TimeSpan timeout)
+ public Task ConnectAsync(TimeSpan timeout)
{
_logger.Info("Connecting [Timeout={0}]", timeout);
- await ExecuteAndWrapExceptionAsync(() => _channel.ConnectAsync().TimeoutAfter(timeout));
+ return ExecuteAndWrapExceptionAsync(() => _channel.ConnectAsync().TimeoutAfter(timeout));
}
- public async Task DisconnectAsync(TimeSpan timeout)
+ public Task DisconnectAsync(TimeSpan timeout)
{
_logger.Info("Disconnecting [Timeout={0}]", timeout);
- await ExecuteAndWrapExceptionAsync(() => _channel.DisconnectAsync().TimeoutAfter(timeout));
+ return ExecuteAndWrapExceptionAsync(() => _channel.DisconnectAsync().TimeoutAfter(timeout));
}
- public async Task SendPacketsAsync(TimeSpan timeout, CancellationToken cancellationToken, IEnumerable packets)
+ public Task SendPacketsAsync(TimeSpan timeout, CancellationToken cancellationToken, IEnumerable packets)
{
- await ExecuteAndWrapExceptionAsync(async () =>
+ return ExecuteAndWrapExceptionAsync(async () =>
{
await _semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
try
diff --git a/Frameworks/MQTTnet.NetStandard/Internal/TaskExtensions.cs b/Frameworks/MQTTnet.NetStandard/Internal/TaskExtensions.cs
index 6acb71ef..bfa01bdb 100644
--- a/Frameworks/MQTTnet.NetStandard/Internal/TaskExtensions.cs
+++ b/Frameworks/MQTTnet.NetStandard/Internal/TaskExtensions.cs
@@ -9,13 +9,15 @@ namespace MQTTnet.Internal
{
public static async Task TimeoutAfter(this Task task, TimeSpan timeout)
{
- using (var cancellationTokenSource = new CancellationTokenSource())
+ if (task == null) throw new ArgumentNullException(nameof(task));
+
+ using (var timeoutCts = new CancellationTokenSource())
{
try
{
- var timeoutTask = Task.Delay(timeout, cancellationTokenSource.Token);
+ var timeoutTask = Task.Delay(timeout, timeoutCts.Token);
var finishedTask = await Task.WhenAny(timeoutTask, task).ConfigureAwait(false);
-
+
if (finishedTask == timeoutTask)
{
throw new MqttCommunicationTimedOutException();
@@ -33,18 +35,20 @@ namespace MQTTnet.Internal
}
finally
{
- cancellationTokenSource.Cancel();
+ timeoutCts.Cancel();
}
}
}
public static async Task TimeoutAfter(this Task task, TimeSpan timeout)
{
- using (var cancellationTokenSource = new CancellationTokenSource())
+ if (task == null) throw new ArgumentNullException(nameof(task));
+
+ using (var timeoutCts = new CancellationTokenSource())
{
try
{
- var timeoutTask = Task.Delay(timeout, cancellationTokenSource.Token);
+ var timeoutTask = Task.Delay(timeout, timeoutCts.Token);
var finishedTask = await Task.WhenAny(timeoutTask, task).ConfigureAwait(false);
if (finishedTask == timeoutTask)
@@ -66,7 +70,7 @@ namespace MQTTnet.Internal
}
finally
{
- cancellationTokenSource.Cancel();
+ timeoutCts.Cancel();
}
}
}
diff --git a/Frameworks/MQTTnet.NetStandard/MQTTnet.Netstandard.csproj b/Frameworks/MQTTnet.NetStandard/MQTTnet.Netstandard.csproj
index f4018cb5..abcc8658 100644
--- a/Frameworks/MQTTnet.NetStandard/MQTTnet.Netstandard.csproj
+++ b/Frameworks/MQTTnet.NetStandard/MQTTnet.Netstandard.csproj
@@ -36,6 +36,10 @@
+
+ RELEASE;NETSTANDARD1_3
+
+
diff --git a/Frameworks/MQTTnet.NetStandard/Server/MqttClientSession.cs b/Frameworks/MQTTnet.NetStandard/Server/MqttClientSession.cs
index 275fcb1b..c5f16a9e 100644
--- a/Frameworks/MQTTnet.NetStandard/Server/MqttClientSession.cs
+++ b/Frameworks/MQTTnet.NetStandard/Server/MqttClientSession.cs
@@ -143,16 +143,16 @@ namespace MQTTnet.Server
private Task ProcessReceivedPacketAsync(IMqttChannelAdapter adapter, MqttBasePacket packet, CancellationToken cancellationToken)
{
- if (packet is MqttPingReqPacket)
- {
- return adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new MqttPingRespPacket());
- }
-
if (packet is MqttPublishPacket publishPacket)
{
return HandleIncomingPublishPacketAsync(adapter, publishPacket, cancellationToken);
}
+ if (packet is MqttPingReqPacket)
+ {
+ return adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new MqttPingRespPacket());
+ }
+
if (packet is MqttPubRelPacket pubRelPacket)
{
return HandleIncomingPubRelPacketAsync(adapter, pubRelPacket, cancellationToken);
diff --git a/Frameworks/MQTTnet.NetStandard/Server/MqttClientSessionsManager.cs b/Frameworks/MQTTnet.NetStandard/Server/MqttClientSessionsManager.cs
index 870e5e09..f65ed2ba 100644
--- a/Frameworks/MQTTnet.NetStandard/Server/MqttClientSessionsManager.cs
+++ b/Frameworks/MQTTnet.NetStandard/Server/MqttClientSessionsManager.cs
@@ -168,7 +168,7 @@ namespace MQTTnet.Server
lock (_sessions)
{
- foreach (var clientSession in _sessions.Values.ToList())
+ foreach (var clientSession in _sessions.Values)
{
clientSession.EnqueueApplicationMessage(applicationMessage);
}
diff --git a/README.md b/README.md
index 57dfce2e..5d3e1867 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ MQTTnet is a high performance .NET library for MQTT based communication. It prov
* TLS 1.2 support for client and server (but not UWP servers)
* Extensible communication channels (i.e. In-Memory, TCP, TCP+TLS, WS)
* Lightweight (only the low level implementation of MQTT, no overhead)
-* Performance optimized (processing ~27.000 messages / second)*
+* Performance optimized (processing ~30.000 messages / second)*
* Interfaces included for mocking and testing
* Access to internal trace messages
* Unit tested (70+ tests)
diff --git a/Tests/MQTTnet.TestApp.NetCore/PerformanceTest.cs b/Tests/MQTTnet.TestApp.NetCore/PerformanceTest.cs
index 301e0fec..1c72b06a 100644
--- a/Tests/MQTTnet.TestApp.NetCore/PerformanceTest.cs
+++ b/Tests/MQTTnet.TestApp.NetCore/PerformanceTest.cs
@@ -43,33 +43,6 @@ namespace MQTTnet.TestApp.NetCore
var client = new MqttFactory().CreateMqttClient();
- client.Connected += async (s, e) =>
- {
- Console.WriteLine("### CONNECTED WITH SERVER ###");
-
- await client.SubscribeAsync(new List
- {
- new TopicFilter("#")
- });
-
- Console.WriteLine("### SUBSCRIBED ###");
- };
-
- client.Disconnected += async (s, e) =>
- {
- Console.WriteLine("### DISCONNECTED FROM SERVER ###");
- await Task.Delay(TimeSpan.FromSeconds(5));
-
- try
- {
- await client.ConnectAsync(options);
- }
- catch
- {
- Console.WriteLine("### RECONNECTING FAILED ###");
- }
- };
-
try
{
await client.ConnectAsync(options);
@@ -79,24 +52,12 @@ namespace MQTTnet.TestApp.NetCore
Console.WriteLine("### CONNECTING FAILED ###" + Environment.NewLine + exception);
}
- Console.WriteLine("### WAITING FOR APPLICATION MESSAGES ###");
-
- var testMessageCount = 10000;
var message = CreateMessage();
- var stopwatch = Stopwatch.StartNew();
- for (var i = 0; i < testMessageCount; i++)
- {
- await client.PublishAsync(message);
- }
-
- stopwatch.Stop();
- Console.WriteLine($"Sent 10.000 messages within {stopwatch.ElapsedMilliseconds} ms ({stopwatch.ElapsedMilliseconds / (float)testMessageCount} ms / message).");
-
var messages = new[] { message };
+
+ var stopwatch = Stopwatch.StartNew();
+
var sentMessagesCount = 0;
-
- stopwatch.Restart();
-
while (stopwatch.ElapsedMilliseconds < 1000)
{
await client.PublishAsync(messages).ConfigureAwait(false);
@@ -104,6 +65,17 @@ namespace MQTTnet.TestApp.NetCore
}
Console.WriteLine($"Sending {sentMessagesCount} messages per second.");
+
+ stopwatch.Restart();
+
+ var testMessageCount = 10000;
+ for (var i = 0; i < testMessageCount; i++)
+ {
+ await client.PublishAsync(message);
+ }
+
+ stopwatch.Stop();
+ Console.WriteLine($"Sent 10.000 messages within {stopwatch.ElapsedMilliseconds} ms ({stopwatch.ElapsedMilliseconds / (float)testMessageCount} ms / message).");
var last = DateTime.Now;
var msgCount = 0;