diff --git a/Directory.Build.props b/Directory.Build.props
index f49be5070..c6146e2b8 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,9 +1,58 @@
+
+ net8.0
+ MQTTnet
+ The contributors of MQTTnet
+ The contributors of MQTTnet
+ Copyright (c) .NET Foundation and Contributors
-
- true
- true
- true
-
+ false
+ false
+ true
+ false
+ enable
-
\ No newline at end of file
+ en-US
+ true
+ 1591;NETSDK1138;NU1803;NU1901;NU1902
+
+ all
+ true
+ low
+
+ true
+ latest
+ recommended
+ default
+
+ true
+ true
+ true
+
+
+
+ true
+
+
+
+ LICENSE
+ nuget.png
+ https://github.com/dotnet/MQTTnet
+ https://github.com/dotnet/MQTTnet.git
+ git
+ true
+ snupkg
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MQTTnet.sln b/MQTTnet.sln
index 15a0d2323..2c1fcd710 100644
--- a/MQTTnet.sln
+++ b/MQTTnet.sln
@@ -7,11 +7,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet", "Source\MQTTnet\M
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B3F60ECB-45BA-4C66-8903-8BB89CA67998}"
ProjectSection(SolutionItems) = preProject
+ .github\workflows\ci.yml = .github\workflows\ci.yml
CODE-OF-CONDUCT.md = CODE-OF-CONDUCT.md
+ Directory.Build.props = Directory.Build.props
LICENSE = LICENSE
README.md = README.md
Source\ReleaseNotes.md = Source\ReleaseNotes.md
- .github\workflows\ci.yml = .github\workflows\ci.yml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.AspNetCore", "Source\MQTTnet.AspnetCore\MQTTnet.AspNetCore.csproj", "{F10C4060-F7EE-4A83-919F-FF723E72F94A}"
@@ -85,6 +86,4 @@ Global
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {07536672-5CBC-4BE3-ACE0-708A431A7894}
EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- EndGlobalSection
EndGlobal
diff --git a/Samples/Client/Client_Connection_Samples.cs b/Samples/Client/Client_Connection_Samples.cs
index 32a8784c7..c68c9d69e 100644
--- a/Samples/Client/Client_Connection_Samples.cs
+++ b/Samples/Client/Client_Connection_Samples.cs
@@ -490,7 +490,7 @@ public static async Task Timeout()
}
}
- class SampleClientKerberosAuthenticationHandler : IMqttEnhancedAuthenticationHandler
+ sealed class SampleClientKerberosAuthenticationHandler : IMqttEnhancedAuthenticationHandler
{
public async Task HandleEnhancedAuthenticationAsync(MqttEnhancedAuthenticationEventArgs eventArgs)
{
diff --git a/Samples/Client/Client_Subscribe_Samples.cs b/Samples/Client/Client_Subscribe_Samples.cs
index 058d3ff91..6f1f4adce 100644
--- a/Samples/Client/Client_Subscribe_Samples.cs
+++ b/Samples/Client/Client_Subscribe_Samples.cs
@@ -142,7 +142,7 @@ public static async Task Subscribe_Topic()
response.DumpToConsole();
}
- static void ConcurrentProcessingDisableAutoAcknowledge(CancellationToken shutdownToken, IMqttClient mqttClient)
+ static void ConcurrentProcessingDisableAutoAcknowledge(IMqttClient mqttClient, CancellationToken shutdownToken)
{
/*
* This sample shows how to achieve concurrent processing and not have message AutoAcknowledged
@@ -170,7 +170,7 @@ async Task ProcessAsync()
};
}
- static void ConcurrentProcessingWithLimit(CancellationToken shutdownToken, IMqttClient mqttClient)
+ static void ConcurrentProcessingWithLimit(IMqttClient mqttClient, CancellationToken shutdownToken)
{
/*
* This sample shows how to achieve concurrent processing, with:
diff --git a/Samples/Diagnostics/Logger_Samples.cs b/Samples/Diagnostics/Logger_Samples.cs
index 1e6d9b2d2..6cd195871 100644
--- a/Samples/Diagnostics/Logger_Samples.cs
+++ b/Samples/Diagnostics/Logger_Samples.cs
@@ -6,6 +6,7 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
+using System.Globalization;
using System.Text;
using MQTTnet.Diagnostics.Logger;
@@ -51,7 +52,7 @@ public static async Task Use_Event_Logger()
mqttEventLogger.LogMessagePublished += (_, args) =>
{
var output = new StringBuilder();
- output.AppendLine($">> [{args.LogMessage.Timestamp:O}] [{args.LogMessage.ThreadId}] [{args.LogMessage.Source}] [{args.LogMessage.Level}]: {args.LogMessage.Message}");
+ output.AppendLine(CultureInfo.InvariantCulture, $">> [{args.LogMessage.Timestamp:O}] [{args.LogMessage.ThreadId}] [{args.LogMessage.Source}] [{args.LogMessage.Level}]: {args.LogMessage.Message}");
if (args.LogMessage.Exception != null)
{
output.AppendLine(args.LogMessage.Exception.ToString());
diff --git a/Samples/Helpers/ObjectExtensions.cs b/Samples/Helpers/ObjectExtensions.cs
index 4384fa923..c87c146e6 100644
--- a/Samples/Helpers/ObjectExtensions.cs
+++ b/Samples/Helpers/ObjectExtensions.cs
@@ -8,17 +8,19 @@ namespace MQTTnet.Samples.Helpers;
internal static class ObjectExtensions
{
+ static readonly JsonSerializerOptions SerializerOptions = new()
+ {
+ WriteIndented = true
+ };
+
public static TObject DumpToConsole(this TObject @object)
{
var output = "NULL";
if (@object != null)
{
- output = JsonSerializer.Serialize(@object, new JsonSerializerOptions
- {
- WriteIndented = true
- });
+ output = JsonSerializer.Serialize(@object, SerializerOptions);
}
-
+
Console.WriteLine($"[{@object?.GetType().Name}]:\r\n{output}");
return @object;
}
diff --git a/Samples/MQTTnet.Samples.csproj b/Samples/MQTTnet.Samples.csproj
index 5fe84d380..3de761aaf 100644
--- a/Samples/MQTTnet.Samples.csproj
+++ b/Samples/MQTTnet.Samples.csproj
@@ -2,19 +2,10 @@
Exe
- net8.0
enable
enable
false
- true
- false
- false
- 1591;NETSDK1138;NU1803;NU1901;NU1902
- true
- all
- true
- low
- latest-Recommended
+ $(NoWarn);CA1707
diff --git a/Samples/Program.cs b/Samples/Program.cs
index 9cf199a22..44e019ee1 100644
--- a/Samples/Program.cs
+++ b/Samples/Program.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Globalization;
using System.Reflection;
Console.BackgroundColor = ConsoleColor.White;
@@ -28,7 +29,7 @@
Console.ResetColor();
var input = Console.ReadLine();
-var selectedIndex = int.Parse(input ?? "0");
+var selectedIndex = int.Parse(input ?? "0", CultureInfo.InvariantCulture);
var selectedSampleClass = sampleClasses[selectedIndex];
var sampleMethods = selectedSampleClass.GetMethods(BindingFlags.Static | BindingFlags.Public).OrderBy(m => m.Name).ToList();
@@ -45,7 +46,7 @@
Console.ResetColor();
input = Console.ReadLine();
-selectedIndex = int.Parse(input ?? "0");
+selectedIndex = int.Parse(input ?? "0", CultureInfo.InvariantCulture);
var selectedSampleMethod = sampleMethods[selectedIndex];
Console.WriteLine();
@@ -58,7 +59,7 @@
{
if (selectedSampleMethod.Invoke(null, null) is Task task)
{
- await task;
+ await task;
}
}
catch (Exception exception)
diff --git a/Samples/Server/Server_ASP_NET_Samples.cs b/Samples/Server/Server_ASP_NET_Samples.cs
index 9247093e2..8f52d114b 100644
--- a/Samples/Server/Server_ASP_NET_Samples.cs
+++ b/Samples/Server/Server_ASP_NET_Samples.cs
@@ -8,6 +8,7 @@
// ReSharper disable EmptyConstructor
// ReSharper disable MemberCanBeMadeStatic.Local
+using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
@@ -52,14 +53,14 @@ public MqttController()
// Inject other services via constructor.
}
- public Task OnClientConnected(ClientConnectedEventArgs eventArgs)
+ public static Task OnClientConnected(ClientConnectedEventArgs eventArgs)
{
Console.WriteLine($"Client '{eventArgs.ClientId}' connected.");
return Task.CompletedTask;
}
- public Task ValidateConnection(ValidatingConnectionEventArgs eventArgs)
+ public static Task ValidateConnection(ValidatingConnectionEventArgs eventArgs)
{
Console.WriteLine($"Client '{eventArgs.ClientId}' wants to connect. Accepting!");
return Task.CompletedTask;
@@ -68,6 +69,7 @@ public Task ValidateConnection(ValidatingConnectionEventArgs eventArgs)
sealed class Startup
{
+ [SuppressMessage("Performance", "CA1822:Mark members as static")]
public void Configure(IApplicationBuilder app, IWebHostEnvironment environment, MqttController mqttController)
{
app.UseRouting();
@@ -88,11 +90,12 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment environment,
* Attach event handlers etc. if required.
*/
- server.ValidatingConnectionAsync += mqttController.ValidateConnection;
- server.ClientConnectedAsync += mqttController.OnClientConnected;
+ server.ValidatingConnectionAsync += MqttController.ValidateConnection;
+ server.ClientConnectedAsync += MqttController.OnClientConnected;
});
}
+ [SuppressMessage("Performance", "CA1822:Mark members as static")]
public void ConfigureServices(IServiceCollection services)
{
services.AddHostedMqttServer(
diff --git a/Samples/Server/Server_Simple_Samples.cs b/Samples/Server/Server_Simple_Samples.cs
index 06eb9e86e..95e167fed 100644
--- a/Samples/Server/Server_Simple_Samples.cs
+++ b/Samples/Server/Server_Simple_Samples.cs
@@ -6,6 +6,7 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
+using System.Globalization;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Protocol;
using MQTTnet.Server;
@@ -161,7 +162,7 @@ static async Task StartMqttServer()
return server;
}
- class ConsoleLogger : IMqttNetLogger
+ sealed class ConsoleLogger : IMqttNetLogger
{
readonly object _consoleSyncRoot = new();
@@ -191,7 +192,7 @@ public void Publish(MqttNetLogLevel logLevel, string source, string message, obj
if (parameters?.Length > 0)
{
- message = string.Format(message, parameters);
+ message = string.Format(CultureInfo.InvariantCulture, message, parameters);
}
lock (_consoleSyncRoot)
diff --git a/Source/MQTTnet.AspTestApp/MQTTnet.AspTestApp.csproj b/Source/MQTTnet.AspTestApp/MQTTnet.AspTestApp.csproj
index 254069b60..9566c7d81 100644
--- a/Source/MQTTnet.AspTestApp/MQTTnet.AspTestApp.csproj
+++ b/Source/MQTTnet.AspTestApp/MQTTnet.AspTestApp.csproj
@@ -1,19 +1,10 @@
- net8.0
enable
enable
false
- true
- false
- false
- 1591;NETSDK1138;NU1803;NU1901;NU1902
- true
- all
- true
- low
- latest-Recommended
+ $(NoWarn);CA1707
diff --git a/Source/MQTTnet.AspTestApp/Pages/Index.cshtml.cs b/Source/MQTTnet.AspTestApp/Pages/Index.cshtml.cs
index e72939925..8b284325f 100644
--- a/Source/MQTTnet.AspTestApp/Pages/Index.cshtml.cs
+++ b/Source/MQTTnet.AspTestApp/Pages/Index.cshtml.cs
@@ -6,7 +6,7 @@
namespace MQTTnet.AspTestApp.Pages;
-public class IndexModel : PageModel
+public partial class IndexModel : PageModel
{
readonly ILogger _logger;
@@ -17,6 +17,9 @@ public IndexModel(ILogger logger)
public void OnGet()
{
- _logger.LogDebug("OnGet");
+ LogOnGet();
}
+
+ [LoggerMessage(Level = LogLevel.Information, Message = "OnGet")]
+ private partial void LogOnGet();
}
\ No newline at end of file
diff --git a/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj b/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj
index ae4708a2e..59646a457 100644
--- a/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj
+++ b/Source/MQTTnet.AspnetCore/MQTTnet.AspNetCore.csproj
@@ -1,59 +1,23 @@
- net8.0
MQTTnet.AspNetCore
MQTTnet.AspNetCore
- True
- The contributors of MQTTnet
- MQTTnet
+ true
+
+ true
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.
- The contributors of MQTTnet
MQTTnet.AspNetCore
- false
- false
- true
- true
- snupkg
- Copyright (c) .NET Foundation and Contributors
- https://github.com/dotnet/MQTTnet
- https://github.com/dotnet/MQTTnet.git
- git
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
- en-US
- false
- false
- nuget.png
- true
- true
- LICENSE
For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/).
- true
- true
+
true
- 1591;NETSDK1138;NU1803;NU1901;NU1902
- true
- all
- true
- low
- low
- latest-Recommended
- true
-
-
-
-
-
-
-
-
-
diff --git a/Source/MQTTnet.AspnetCore/MqttClientConnectionContextFactory.cs b/Source/MQTTnet.AspnetCore/MqttClientConnectionContextFactory.cs
index fadf90659..3c751cb4a 100644
--- a/Source/MQTTnet.AspnetCore/MqttClientConnectionContextFactory.cs
+++ b/Source/MQTTnet.AspnetCore/MqttClientConnectionContextFactory.cs
@@ -13,7 +13,7 @@ public sealed class MqttClientConnectionContextFactory : IMqttClientAdapterFacto
{
public IMqttChannelAdapter CreateClientAdapter(MqttClientOptions options, MqttPacketInspector packetInspector, IMqttNetLogger logger)
{
- if (options == null) throw new ArgumentNullException(nameof(options));
+ ArgumentNullException.ThrowIfNull(options);
switch (options.ChannelOptions)
{
diff --git a/Source/MQTTnet.AspnetCore/MqttSubProtocolSelector.cs b/Source/MQTTnet.AspnetCore/MqttSubProtocolSelector.cs
index c6acdfa8e..6044f8d4d 100644
--- a/Source/MQTTnet.AspnetCore/MqttSubProtocolSelector.cs
+++ b/Source/MQTTnet.AspnetCore/MqttSubProtocolSelector.cs
@@ -29,6 +29,6 @@ public static string SelectSubProtocol(IList requestedSubProtocolValues)
ArgumentNullException.ThrowIfNull(requestedSubProtocolValues);
// Order the protocols to also match "mqtt", "mqttv-3.1", "mqttv-3.11" etc.
- return requestedSubProtocolValues.OrderByDescending(p => p.Length).FirstOrDefault(p => p.ToLower().StartsWith("mqtt"));
+ return requestedSubProtocolValues.OrderByDescending(p => p.Length).FirstOrDefault(p => p.ToLowerInvariant().StartsWith("mqtt", StringComparison.InvariantCulture));
}
}
\ No newline at end of file
diff --git a/Source/MQTTnet.AspnetCore/SocketConnection.cs b/Source/MQTTnet.AspnetCore/SocketConnection.cs
index ee5f1cb3d..7bc2d9e9f 100644
--- a/Source/MQTTnet.AspnetCore/SocketConnection.cs
+++ b/Source/MQTTnet.AspnetCore/SocketConnection.cs
@@ -81,7 +81,7 @@ public async Task StartAsync()
IsConnected = true;
}
- static Exception ConnectionAborted()
+ static MqttCommunicationException ConnectionAborted()
{
return new MqttCommunicationException("Connection Aborted");
}
@@ -218,12 +218,16 @@ async Task ProcessReceives()
var flushTask = _application.Output.FlushAsync();
+ FlushResult result;
if (!flushTask.IsCompleted)
{
- await flushTask;
+ result = await flushTask;
+ }
+ else
+ {
+ result = flushTask.GetAwaiter().GetResult();
}
- var result = flushTask.GetAwaiter().GetResult();
if (result.IsCompleted)
{
// Pipe consumer is shut down, do we stop writing
diff --git a/Source/MQTTnet.AspnetCore/SocketReceiver.cs b/Source/MQTTnet.AspnetCore/SocketReceiver.cs
index f8b628fb5..f0888e01f 100644
--- a/Source/MQTTnet.AspnetCore/SocketReceiver.cs
+++ b/Source/MQTTnet.AspnetCore/SocketReceiver.cs
@@ -8,7 +8,7 @@
namespace MQTTnet.AspNetCore;
-public sealed class SocketReceiver
+public sealed class SocketReceiver : IDisposable
{
readonly SocketAwaitable _awaitable;
readonly SocketAsyncEventArgs _eventArgs = new();
@@ -33,4 +33,9 @@ public SocketAwaitable ReceiveAsync(Memory buffer)
return _awaitable;
}
+
+ public void Dispose()
+ {
+ _eventArgs.Dispose();
+ }
}
\ No newline at end of file
diff --git a/Source/MQTTnet.AspnetCore/SocketSender.cs b/Source/MQTTnet.AspnetCore/SocketSender.cs
index fc06ea6cf..1c4725c17 100644
--- a/Source/MQTTnet.AspnetCore/SocketSender.cs
+++ b/Source/MQTTnet.AspnetCore/SocketSender.cs
@@ -12,7 +12,7 @@
namespace MQTTnet.AspNetCore;
-public sealed class SocketSender
+public sealed class SocketSender : IDisposable
{
readonly SocketAwaitable _awaitable;
readonly SocketAsyncEventArgs _eventArgs = new();
@@ -28,6 +28,11 @@ public SocketSender(Socket socket, PipeScheduler scheduler)
_eventArgs.Completed += (_, e) => ((SocketAwaitable)e.UserToken).Complete(e.BytesTransferred, e.SocketError);
}
+ public void Dispose()
+ {
+ _eventArgs.Dispose();
+ }
+
public SocketAwaitable SendAsync(in ReadOnlySequence buffers)
{
if (buffers.IsSingleSegment)
diff --git a/Source/MQTTnet.Benchmarks/AsyncLockBenchmark.cs b/Source/MQTTnet.Benchmarks/AsyncLockBenchmark.cs
index 4912fcf48..af7224e89 100644
--- a/Source/MQTTnet.Benchmarks/AsyncLockBenchmark.cs
+++ b/Source/MQTTnet.Benchmarks/AsyncLockBenchmark.cs
@@ -43,7 +43,7 @@ public async Task Synchronize_100_Tasks()
if (globalI != tasksCount)
{
- throw new Exception($"Code is broken ({globalI})!");
+ throw new InvalidOperationException($"Code is broken ({globalI})!");
}
}
diff --git a/Source/MQTTnet.Benchmarks/ChannelAdapterBenchmark.cs b/Source/MQTTnet.Benchmarks/ChannelAdapterBenchmark.cs
index 7942cee56..fdc7ddbc8 100644
--- a/Source/MQTTnet.Benchmarks/ChannelAdapterBenchmark.cs
+++ b/Source/MQTTnet.Benchmarks/ChannelAdapterBenchmark.cs
@@ -15,7 +15,7 @@
namespace MQTTnet.Benchmarks;
[MemoryDiagnoser]
-public sealed class ChannelAdapterBenchmark : BaseBenchmark
+public sealed class ChannelAdapterBenchmark : BaseBenchmark, IDisposable
{
MqttChannelAdapter _channelAdapter;
int _iterations;
@@ -86,4 +86,10 @@ static byte[] Join(params ArraySegment[] chunks)
return buffer.ToArray();
}
+
+ public void Dispose()
+ {
+ _channelAdapter?.Dispose();
+ _stream?.Dispose();
+ }
}
\ No newline at end of file
diff --git a/Source/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj b/Source/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj
index 1b551ac13..4f1dbbafa 100644
--- a/Source/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj
+++ b/Source/MQTTnet.Benchmarks/MQTTnet.Benchmarks.csproj
@@ -1,20 +1,11 @@
- true
Exe
Full
- net8.0
false
- false
- false
- true
- 1591;NETSDK1138;NU1803;NU1901;NU1902;CS8892
+ $(NoWarn);CS8892;CA1707;CA1051;CA1822
false
- all
- true
- low
- latest-Recommended
diff --git a/Source/MQTTnet.Benchmarks/MessageDeliveryBenchmark.cs b/Source/MQTTnet.Benchmarks/MessageDeliveryBenchmark.cs
index bca655291..66f8bfcfa 100644
--- a/Source/MQTTnet.Benchmarks/MessageDeliveryBenchmark.cs
+++ b/Source/MQTTnet.Benchmarks/MessageDeliveryBenchmark.cs
@@ -2,10 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using MQTTnet.Packets;
using MQTTnet.Server;
@@ -13,7 +9,7 @@
namespace MQTTnet.Benchmarks;
[MemoryDiagnoser]
-public class MessageDeliveryBenchmark : BaseBenchmark
+public sealed class MessageDeliveryBenchmark : BaseBenchmark, IDisposable
{
List _allSubscribedTopics; // Keep track of the subset of topics that are subscribed
CancellationTokenSource _cancellationTokenSource;
@@ -99,10 +95,16 @@ public void DeliverMessages()
if (_messagesReceivedCount < _messagesExpectedCount)
{
- throw new Exception($"Messages Received Count mismatch, expected {_messagesExpectedCount}, received {_messagesReceivedCount}");
+ throw new InvalidOperationException($"Messages Received Count mismatch, expected {_messagesExpectedCount}, received {_messagesReceivedCount}");
}
}
+ public void Dispose()
+ {
+ _cancellationTokenSource?.Dispose();
+ _mqttServer?.Dispose();
+ }
+
[GlobalSetup]
public void Setup()
{
@@ -173,7 +175,7 @@ public void Setup()
var topicIndexStep = totalNumTopics / (_numSubscribedTopicsPerSubscriber * _numSubscribers);
if (topicIndexStep * _numSubscribedTopicsPerSubscriber * _numSubscribers != totalNumTopics)
{
- throw new Exception(
+ throw new InvalidOperationException(
$"The total number of topics must be divisible by the number of subscribed topics across all subscribers. Total number of topics: {totalNumTopics}, topic step: {topicIndexStep}");
}
diff --git a/Source/MQTTnet.Benchmarks/MqttTcpChannelBenchmark.cs b/Source/MQTTnet.Benchmarks/MqttTcpChannelBenchmark.cs
index fce8cf1eb..f0bce1479 100644
--- a/Source/MQTTnet.Benchmarks/MqttTcpChannelBenchmark.cs
+++ b/Source/MQTTnet.Benchmarks/MqttTcpChannelBenchmark.cs
@@ -4,8 +4,6 @@
using System.Buffers;
using System.Reflection;
-using System.Threading;
-using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using MQTTnet.Channel;
@@ -18,9 +16,9 @@ namespace MQTTnet.Benchmarks;
[SimpleJob(RuntimeMoniker.Net60)]
[MemoryDiagnoser]
-public class MqttTcpChannelBenchmark : BaseBenchmark
+public sealed class MqttTcpChannelBenchmark : BaseBenchmark, IDisposable
{
- IMqttChannel _clientChannel;
+ MqttTcpChannel _clientChannel;
MqttServer _mqttServer;
IMqttChannel _serverChannel;
@@ -84,4 +82,11 @@ async Task WriteAsync(int iterations, int size)
await _serverChannel.WriteAsync(buffer, true, CancellationToken.None).ConfigureAwait(false);
}
}
+
+ public void Dispose()
+ {
+ _clientChannel?.Dispose();
+ _mqttServer?.Dispose();
+ _serverChannel?.Dispose();
+ }
}
\ No newline at end of file
diff --git a/Source/MQTTnet.Benchmarks/Program.cs b/Source/MQTTnet.Benchmarks/Program.cs
index 481f87faa..64dddfdeb 100644
--- a/Source/MQTTnet.Benchmarks/Program.cs
+++ b/Source/MQTTnet.Benchmarks/Program.cs
@@ -92,7 +92,7 @@ static void HandleArguments(string[] arguments)
return;
}
- _selectedBenchmarkIndex = _benchmarks.FindIndex(b => b.Name.Equals(arguments[0]));
+ _selectedBenchmarkIndex = _benchmarks.FindIndex(b => b.Name.Equals(arguments[0], StringComparison.Ordinal));
if (_selectedBenchmarkIndex < 0)
{
diff --git a/Source/MQTTnet.Benchmarks/ReaderExtensionsBenchmark.cs b/Source/MQTTnet.Benchmarks/ReaderExtensionsBenchmark.cs
index 1779a57d9..d4f869559 100644
--- a/Source/MQTTnet.Benchmarks/ReaderExtensionsBenchmark.cs
+++ b/Source/MQTTnet.Benchmarks/ReaderExtensionsBenchmark.cs
@@ -13,7 +13,7 @@ namespace MQTTnet.Benchmarks;
[SimpleJob(RuntimeMoniker.Net60)]
[RPlotExporter, RankColumn]
[MemoryDiagnoser]
-public class ReaderExtensionsBenchmark
+public sealed class ReaderExtensionsBenchmark : IDisposable, IAsyncDisposable
{
MqttPacketFormatterAdapter _mqttPacketFormatter;
MemoryStream _stream;
@@ -83,4 +83,17 @@ public async Task After()
}
}
}
+
+ public void Dispose()
+ {
+ _stream?.Dispose();
+ }
+
+ public async ValueTask DisposeAsync()
+ {
+ if (_stream != null)
+ {
+ await _stream.DisposeAsync();
+ }
+ }
}
\ No newline at end of file
diff --git a/Source/MQTTnet.Benchmarks/SendPacketAsyncBenchmark.cs b/Source/MQTTnet.Benchmarks/SendPacketAsyncBenchmark.cs
index 82f145538..8b46d7874 100644
--- a/Source/MQTTnet.Benchmarks/SendPacketAsyncBenchmark.cs
+++ b/Source/MQTTnet.Benchmarks/SendPacketAsyncBenchmark.cs
@@ -1,28 +1,35 @@
+using System.Buffers;
+using System.IO.Pipelines;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using MQTTnet.Formatter;
-using System;
-using System.Buffers;
-using System.IO;
-using System.IO.Pipelines;
-using System.Threading.Tasks;
namespace MQTTnet.Benchmarks;
[SimpleJob(RuntimeMoniker.Net60)]
-[RPlotExporter, RankColumn]
+[RPlotExporter]
+[RankColumn]
[MemoryDiagnoser]
-public class SendPacketAsyncBenchmark : BaseBenchmark
+public sealed class SendPacketAsyncBenchmark : BaseBenchmark, IDisposable, IAsyncDisposable
{
- MemoryStream _stream;
MqttPacketBuffer _buffer;
+ MemoryStream _stream;
- [GlobalSetup]
- public void GlobalSetup()
+ [Benchmark]
+ public async ValueTask After()
{
- _stream = new MemoryStream(1024);
- var packet = new ArraySegment(new byte[10]);
- _buffer = new MqttPacketBuffer(packet);
+ _stream.Position = 0;
+ var output = PipeWriter.Create(_stream);
+
+ if (_buffer.Payload.Length == 0)
+ {
+ await output.WriteAsync(_buffer.Packet).ConfigureAwait(false);
+ }
+ else
+ {
+ WritePacketBuffer(output, _buffer);
+ await output.FlushAsync().ConfigureAwait(false);
+ }
}
[Benchmark(Baseline = true)]
@@ -35,23 +42,27 @@ public async ValueTask Before()
await output.FlushAsync();
}
- [Benchmark]
- public async ValueTask After()
+ public void Dispose()
{
- _stream.Position = 0;
- var output = PipeWriter.Create(_stream);
+ _stream?.Dispose();
+ }
- if (_buffer.Payload.Length == 0)
- {
- await output.WriteAsync(_buffer.Packet).ConfigureAwait(false);
- }
- else
+ public async ValueTask DisposeAsync()
+ {
+ if (_stream != null)
{
- WritePacketBuffer(output, _buffer);
- await output.FlushAsync().ConfigureAwait(false);
+ await _stream.DisposeAsync();
}
}
+ [GlobalSetup]
+ public void GlobalSetup()
+ {
+ _stream = new MemoryStream(1024);
+ var packet = new ArraySegment(new byte[10]);
+ _buffer = new MqttPacketBuffer(packet);
+ }
+
static void WritePacketBuffer(PipeWriter output, MqttPacketBuffer buffer)
{
// copy MqttPacketBuffer's Packet and Payload to the same buffer block of PipeWriter
diff --git a/Source/MQTTnet.Benchmarks/SerializerBenchmark.cs b/Source/MQTTnet.Benchmarks/SerializerBenchmark.cs
index 721f2c0b4..d11d955a4 100644
--- a/Source/MQTTnet.Benchmarks/SerializerBenchmark.cs
+++ b/Source/MQTTnet.Benchmarks/SerializerBenchmark.cs
@@ -26,7 +26,7 @@ public class SerializerBenchmark : BaseBenchmark
{
MqttPacket _packet;
ArraySegment _serializedPacket;
- IMqttPacketFormatter _serializer;
+ MqttV3PacketFormatter _serializer;
MqttBufferWriter _bufferWriter;
[GlobalSetup]
@@ -43,7 +43,7 @@ public void GlobalSetup()
}
[Benchmark]
- public void Serialize_10000_Messages()
+ public void Serialize10000Messages()
{
for (var i = 0; i < 10000; i++)
{
@@ -53,7 +53,7 @@ public void Serialize_10000_Messages()
}
[Benchmark]
- public void Deserialize_10000_Messages()
+ public void Deserialize10000Messages()
{
var channel = new BenchmarkMqttChannel(_serializedPacket);
var reader = new MqttChannelAdapter(channel, new MqttPacketFormatterAdapter(new MqttBufferWriter(4096, 65535)), new MqttNetEventLogger());
@@ -66,7 +66,7 @@ public void Deserialize_10000_Messages()
}
}
- class BenchmarkMqttChannel : IMqttChannel
+ sealed class BenchmarkMqttChannel : IMqttChannel
{
readonly ArraySegment _buffer;
int _position;
@@ -81,7 +81,7 @@ public BenchmarkMqttChannel(ArraySegment buffer)
public EndPoint LocalEndPoint { get; set; }
- public bool IsSecureConnection { get; } = false;
+ public bool IsSecureConnection { get; }
public X509Certificate2 ClientCertificate { get; set; }
diff --git a/Source/MQTTnet.Extensions.Rpc/DefaultMqttRpcClientTopicGenerationStrategy.cs b/Source/MQTTnet.Extensions.Rpc/DefaultMqttRpcClientTopicGenerationStrategy.cs
index 13d789582..1d3c43058 100644
--- a/Source/MQTTnet.Extensions.Rpc/DefaultMqttRpcClientTopicGenerationStrategy.cs
+++ b/Source/MQTTnet.Extensions.Rpc/DefaultMqttRpcClientTopicGenerationStrategy.cs
@@ -12,7 +12,7 @@ public MqttRpcTopicPair CreateRpcTopics(TopicGenerationContext context)
{
ArgumentNullException.ThrowIfNull(context);
- if (context.MethodName.Contains("/") || context.MethodName.Contains("+") || context.MethodName.Contains("#"))
+ if (context.MethodName.Contains('/') || context.MethodName.Contains('+') || context.MethodName.Contains('#'))
{
throw new ArgumentException("The method name cannot contain /, + or #.");
}
diff --git a/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj b/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj
index 41a84f4e9..d300ebc9b 100644
--- a/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj
+++ b/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj
@@ -1,53 +1,19 @@
- net8.0
MQTTnet.Extensions.Rpc
MQTTnet.Extensions.Rpc
+ true
+
True
- The contributors of MQTTnet
- MQTTnet
This is an extension library which allows executing synchronous device calls including a response using MQTTnet.
- The contributors of MQTTnet
MQTTnet.Extensions.Rpc
- false
- false
- true
- true
- snupkg
- Copyright (c) .NET Foundation and Contributors
- https://github.com/dotnet/MQTTnet
- https://github.com/dotnet/MQTTnet.git
- git
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
- en-US
- false
- false
- nuget.png
true
- true
- LICENSE
For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/).
- true
true
- 1591;NETSDK1138;NU1803;NU1901;NU1902
- true
- all
- true
- low
- latest-Recommended
- true
-
-
-
-
-
-
-
-
-
diff --git a/Source/MQTTnet.Extensions.Rpc/MqttRpcClientExtensions.cs b/Source/MQTTnet.Extensions.Rpc/MqttRpcClientExtensions.cs
index bde8aefcc..8e0e42a53 100644
--- a/Source/MQTTnet.Extensions.Rpc/MqttRpcClientExtensions.cs
+++ b/Source/MQTTnet.Extensions.Rpc/MqttRpcClientExtensions.cs
@@ -14,7 +14,7 @@ public static class MqttRpcClientExtensions
{
public static Task ExecuteAsync(this IMqttRpcClient client, TimeSpan timeout, string methodName, string payload, MqttQualityOfServiceLevel qualityOfServiceLevel, IDictionary parameters = null)
{
- if (client == null) throw new ArgumentNullException(nameof(client));
+ ArgumentNullException.ThrowIfNull(client);
var buffer = Encoding.UTF8.GetBytes(payload ?? string.Empty);
diff --git a/Source/MQTTnet.Extensions.TopicTemplate/MQTTnet.Extensions.TopicTemplate.csproj b/Source/MQTTnet.Extensions.TopicTemplate/MQTTnet.Extensions.TopicTemplate.csproj
index cef08d804..e0c4f296f 100644
--- a/Source/MQTTnet.Extensions.TopicTemplate/MQTTnet.Extensions.TopicTemplate.csproj
+++ b/Source/MQTTnet.Extensions.TopicTemplate/MQTTnet.Extensions.TopicTemplate.csproj
@@ -1,54 +1,24 @@
- net8.0
MQTTnet.Extensions.TopicTemplate
MQTTnet.Extensions.TopicTemplate
+ true
+
True
- The contributors of MQTTnet
- MQTTnet
Provides mqtt topic templating logic to support dispatch,
routing and similar functionality based on the well known moustache syntax (AsyncAPI compatible).
README.md
- The contributors of MQTTnet
MQTTnet.Extensions.TopicTemplate
- false
- false
- true
- true
- snupkg
- Copyright (c) .NET Foundation and Contributors
- https://github.com/dotnet/MQTTnet
- https://github.com/dotnet/MQTTnet.git
- git
MQTT Message Queue Telemetry MQTTClient Messaging Routing AsyncAPI Template
- en-US
- nuget.png
- true
- true
- LICENSE
For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/).
true
- 1591;NETSDK1138
- true
-
-
-
-
- True
- \
-
-
-
-
-
-
+
-
diff --git a/Source/MQTTnet.Extensions.TopicTemplate/MqttTopicTemplate.cs b/Source/MQTTnet.Extensions.TopicTemplate/MqttTopicTemplate.cs
index 30dbf6e58..029a9d548 100644
--- a/Source/MQTTnet.Extensions.TopicTemplate/MqttTopicTemplate.cs
+++ b/Source/MQTTnet.Extensions.TopicTemplate/MqttTopicTemplate.cs
@@ -84,13 +84,13 @@ public string TopicTreeRootFilter
{
var filter = TopicFilter;
// append slash if neccessary
- if (filter.Length > 0 && !filter.EndsWith(MqttTopicFilterComparer.LevelSeparator.ToString()) && !filter.EndsWith(MqttTopicFilterComparer.MultiLevelWildcard.ToString()))
+ if (filter.Length > 0 && !filter.EndsWith(MqttTopicFilterComparer.LevelSeparator) && !filter.EndsWith(MqttTopicFilterComparer.MultiLevelWildcard))
{
filter += MqttTopicFilterComparer.LevelSeparator;
}
// append hash if neccessary
- if (!filter.EndsWith(MqttTopicFilterComparer.MultiLevelWildcard.ToString()))
+ if (!filter.EndsWith(MqttTopicFilterComparer.MultiLevelWildcard))
{
filter += MqttTopicFilterComparer.MultiLevelWildcard;
}
@@ -161,12 +161,12 @@ string CommonPrefix(string a, string b)
return new MqttTopicTemplate(MqttTopicFilterComparer.MultiLevelWildcard.ToString());
}
- if (root.Contains(MqttTopicFilterComparer.LevelSeparator) && !root.EndsWith(MqttTopicFilterComparer.LevelSeparator.ToString()) && !root.EndsWith("}"))
+ if (root.Contains(MqttTopicFilterComparer.LevelSeparator) && !root.EndsWith(MqttTopicFilterComparer.LevelSeparator.ToString(), StringComparison.InvariantCulture) && !root.EndsWith('}'))
{
root = root.Substring(0, root.LastIndexOf(MqttTopicFilterComparer.LevelSeparator) + 1);
}
- if (root.EndsWith(MqttTopicFilterComparer.LevelSeparator.ToString()))
+ if (root.EndsWith(MqttTopicFilterComparer.LevelSeparator.ToString(), StringComparison.InvariantCulture))
{
root += MqttTopicFilterComparer.SingleLevelWildcard;
}
diff --git a/Source/MQTTnet.Server/EnhancedAuthentication/ExchangeEnhancedAuthenticationOptionsFactory.cs b/Source/MQTTnet.Server/EnhancedAuthentication/ExchangeEnhancedAuthenticationOptionsFactory.cs
index 1b55e3b4e..5396d3f68 100644
--- a/Source/MQTTnet.Server/EnhancedAuthentication/ExchangeEnhancedAuthenticationOptionsFactory.cs
+++ b/Source/MQTTnet.Server/EnhancedAuthentication/ExchangeEnhancedAuthenticationOptionsFactory.cs
@@ -53,10 +53,7 @@ public ExchangeEnhancedAuthenticationOptionsFactory WithUserProperties(List
public string ClientId { get; }
- ///
- /// Gets the user name of the client.
- ///
- public string UserName { get; }
-
public bool CloseConnection { get; set; }
///
@@ -45,10 +40,15 @@ public InterceptingPublishEventArgs(MqttApplicationMessage applicationMessage, C
///
/// Gets the response which will be sent to the client via the PUBACK etc. packets.
///
- public PublishResponse Response { get; } = new PublishResponse();
+ public PublishResponse Response { get; } = new();
///
/// Gets or sets a key/value collection that can be used to share data within the scope of this session.
///
public IDictionary SessionItems { get; }
+
+ ///
+ /// Gets the user name of the client.
+ ///
+ public string UserName { get; }
}
\ No newline at end of file
diff --git a/Source/MQTTnet.Server/Events/InterceptingSubscriptionEventArgs.cs b/Source/MQTTnet.Server/Events/InterceptingSubscriptionEventArgs.cs
index 69c532c9f..4bfd3ec0f 100644
--- a/Source/MQTTnet.Server/Events/InterceptingSubscriptionEventArgs.cs
+++ b/Source/MQTTnet.Server/Events/InterceptingSubscriptionEventArgs.cs
@@ -10,12 +10,12 @@ namespace MQTTnet.Server;
public sealed class InterceptingSubscriptionEventArgs : EventArgs
{
public InterceptingSubscriptionEventArgs(
- CancellationToken cancellationToken,
string clientId,
string userName,
MqttSessionStatus session,
MqttTopicFilter topicFilter,
- List userProperties)
+ List userProperties,
+ CancellationToken cancellationToken)
{
CancellationToken = cancellationToken;
ClientId = clientId;
@@ -36,11 +36,6 @@ public InterceptingSubscriptionEventArgs(
///
public string ClientId { get; }
- ///
- /// Gets the user name of the client.
- ///
- public string UserName { get; }
-
///
/// Gets or sets whether the broker should close the client connection.
///
@@ -61,7 +56,7 @@ public InterceptingSubscriptionEventArgs(
///
/// Gets the response which will be sent to the client via the SUBACK packet.
///
- public SubscribeResponse Response { get; } = new SubscribeResponse();
+ public SubscribeResponse Response { get; } = new();
///
/// Gets the current client session.
@@ -79,6 +74,11 @@ public InterceptingSubscriptionEventArgs(
///
public MqttTopicFilter TopicFilter { get; set; }
+ ///
+ /// Gets the user name of the client.
+ ///
+ public string UserName { get; }
+
///
/// Gets or sets the user properties.
/// MQTT 5.0.0+ feature.
diff --git a/Source/MQTTnet.Server/Events/InterceptingUnsubscriptionEventArgs.cs b/Source/MQTTnet.Server/Events/InterceptingUnsubscriptionEventArgs.cs
index 053fdbb42..0400108d4 100644
--- a/Source/MQTTnet.Server/Events/InterceptingUnsubscriptionEventArgs.cs
+++ b/Source/MQTTnet.Server/Events/InterceptingUnsubscriptionEventArgs.cs
@@ -9,7 +9,7 @@ namespace MQTTnet.Server;
public sealed class InterceptingUnsubscriptionEventArgs : EventArgs
{
- public InterceptingUnsubscriptionEventArgs(CancellationToken cancellationToken, string clientId, string userName, IDictionary sessionItems, string topic, List userProperties)
+ public InterceptingUnsubscriptionEventArgs(string clientId, string userName, IDictionary sessionItems, string topic, List userProperties, CancellationToken cancellationToken)
{
CancellationToken = cancellationToken;
ClientId = clientId;
diff --git a/Source/MQTTnet.Server/Internal/MqttClientSessionsManager.cs b/Source/MQTTnet.Server/Internal/MqttClientSessionsManager.cs
index b4985bd2d..9ea017349 100644
--- a/Source/MQTTnet.Server/Internal/MqttClientSessionsManager.cs
+++ b/Source/MQTTnet.Server/Internal/MqttClientSessionsManager.cs
@@ -131,7 +131,7 @@ public async Task DispatchApplicationMessage(
// Allow the user to intercept application message...
if (_eventContainer.InterceptingPublishEvent.HasHandlers)
{
- var interceptingPublishEventArgs = new InterceptingPublishEventArgs(applicationMessage, cancellationToken, senderId, senderUserName, senderSessionItems);
+ var interceptingPublishEventArgs = new InterceptingPublishEventArgs(applicationMessage, senderId, senderUserName, senderSessionItems, cancellationToken);
if (string.IsNullOrEmpty(interceptingPublishEventArgs.ApplicationMessage.Topic))
{
// This can happen if a topic alias us used but the topic is
@@ -437,7 +437,7 @@ public async Task HandleClientConnectionAsync(IMqttChannelAdapter channelAdapter
}
}
- public void OnSubscriptionsAdded(MqttSession clientSession, List topics)
+ public void OnSubscriptionsAdded(MqttSession clientSession, List subscriptionsTopics)
{
_sessionsManagementLock.EnterWriteLock();
try
@@ -448,7 +448,7 @@ public void OnSubscriptionsAdded(MqttSession clientSession, List topics)
_subscriberSessions.Add(clientSession);
}
- foreach (var topic in topics)
+ foreach (var topic in subscriptionsTopics)
{
clientSession.AddSubscribedTopic(topic);
}
diff --git a/Source/MQTTnet.Server/Internal/MqttClientSubscriptionsManager.cs b/Source/MQTTnet.Server/Internal/MqttClientSubscriptionsManager.cs
index 381a155eb..df290fb4f 100644
--- a/Source/MQTTnet.Server/Internal/MqttClientSubscriptionsManager.cs
+++ b/Source/MQTTnet.Server/Internal/MqttClientSubscriptionsManager.cs
@@ -81,7 +81,7 @@ public CheckSubscriptionsResult CheckSubscriptions(string topic, ulong topicHash
return CheckSubscriptionsResult.NotSubscribed;
}
- var senderIsReceiver = string.Equals(senderId, _session.Id);
+ var senderIsReceiver = string.Equals(senderId, _session.Id, StringComparison.Ordinal);
var maxQoSLevel = -1; // Not subscribed.
HashSet subscriptionIdentifiers = null;
@@ -460,7 +460,7 @@ async Task InterceptSubscribe(
List userProperties,
CancellationToken cancellationToken)
{
- var eventArgs = new InterceptingSubscriptionEventArgs(cancellationToken, _session.Id, _session.UserName, new MqttSessionStatus(_session), topicFilter, userProperties);
+ var eventArgs = new InterceptingSubscriptionEventArgs(_session.Id, _session.UserName, new MqttSessionStatus(_session), topicFilter, userProperties, cancellationToken);
if (topicFilter.QualityOfServiceLevel == MqttQualityOfServiceLevel.AtMostOnce)
{
@@ -475,7 +475,7 @@ async Task InterceptSubscribe(
eventArgs.Response.ReasonCode = MqttSubscribeReasonCode.GrantedQoS2;
}
- if (topicFilter.Topic.StartsWith("$share/"))
+ if (topicFilter.Topic.StartsWith("$share/", StringComparison.InvariantCulture))
{
eventArgs.Response.ReasonCode = MqttSubscribeReasonCode.SharedSubscriptionsNotSupported;
}
@@ -493,7 +493,7 @@ async Task InterceptUnsubscribe(
List userProperties,
CancellationToken cancellationToken)
{
- var clientUnsubscribingTopicEventArgs = new InterceptingUnsubscriptionEventArgs(cancellationToken, _session.Id, _session.UserName, _session.Items, topicFilter, userProperties)
+ var clientUnsubscribingTopicEventArgs = new InterceptingUnsubscriptionEventArgs(_session.Id, _session.UserName, _session.Items, topicFilter, userProperties, cancellationToken)
{
Response =
{
diff --git a/Source/MQTTnet.Server/Internal/MqttConnectedClient.cs b/Source/MQTTnet.Server/Internal/MqttConnectedClient.cs
index cb765f1eb..48e6bd2c7 100644
--- a/Source/MQTTnet.Server/Internal/MqttConnectedClient.cs
+++ b/Source/MQTTnet.Server/Internal/MqttConnectedClient.cs
@@ -156,7 +156,7 @@ public async Task StopAsync(MqttServerClientDisconnectOptions disconnectOptions)
// TODO: Maybe adding a configuration option is requested in the future.
if (disconnectOptions != null)
{
- if (disconnectOptions.ReasonCode != MqttDisconnectReasonCode.NormalDisconnection || disconnectOptions.UserProperties?.Any() == true ||
+ if (disconnectOptions.ReasonCode != MqttDisconnectReasonCode.NormalDisconnection || disconnectOptions.UserProperties?.Count > 0 ||
!string.IsNullOrEmpty(disconnectOptions.ReasonString) || !string.IsNullOrEmpty(disconnectOptions.ServerReference))
{
// It is very important to send the DISCONNECT packet here BEFORE cancelling the
@@ -349,7 +349,7 @@ async Task InterceptPacketAsync(MqttPacket packet, CancellationToken
return packet;
}
- var interceptingPacketEventArgs = new InterceptingPacketEventArgs(cancellationToken, Id, UserName, RemoteEndPoint, packet, Session.Items);
+ var interceptingPacketEventArgs = new InterceptingPacketEventArgs(Id, UserName, RemoteEndPoint, packet, Session.Items, cancellationToken);
await _eventContainer.InterceptingOutboundPacketEvent.InvokeAsync(interceptingPacketEventArgs).ConfigureAwait(false);
if (!interceptingPacketEventArgs.ProcessPacket || packet == null)
@@ -395,7 +395,7 @@ async Task ReceivePackagesLoop(CancellationToken cancellationToken)
if (_eventContainer.InterceptingInboundPacketEvent.HasHandlers)
{
- var interceptingPacketEventArgs = new InterceptingPacketEventArgs(cancellationToken, Id, UserName, RemoteEndPoint, currentPacket, Session.Items);
+ var interceptingPacketEventArgs = new InterceptingPacketEventArgs(Id, UserName, RemoteEndPoint, currentPacket, Session.Items, cancellationToken);
await _eventContainer.InterceptingInboundPacketEvent.InvokeAsync(interceptingPacketEventArgs).ConfigureAwait(false);
currentPacket = interceptingPacketEventArgs.Packet;
processPacket = interceptingPacketEventArgs.ProcessPacket;
diff --git a/Source/MQTTnet.Server/Internal/MqttRetainedMessagesManager.cs b/Source/MQTTnet.Server/Internal/MqttRetainedMessagesManager.cs
index 1c86489ed..8b5a41c33 100644
--- a/Source/MQTTnet.Server/Internal/MqttRetainedMessagesManager.cs
+++ b/Source/MQTTnet.Server/Internal/MqttRetainedMessagesManager.cs
@@ -7,13 +7,12 @@
namespace MQTTnet.Server.Internal;
-public sealed class MqttRetainedMessagesManager
+public sealed class MqttRetainedMessagesManager : IDisposable
{
- readonly Dictionary _messages = new(4096);
- readonly AsyncLock _storageAccessLock = new();
-
readonly MqttServerEventContainer _eventContainer;
readonly MqttNetSourceLogger _logger;
+ readonly Dictionary _messages = new(4096);
+ readonly AsyncLock _storageAccessLock = new();
public MqttRetainedMessagesManager(MqttServerEventContainer eventContainer, IMqttNetLogger logger)
{
@@ -24,6 +23,46 @@ public MqttRetainedMessagesManager(MqttServerEventContainer eventContainer, IMqt
_logger = logger.WithSource(nameof(MqttRetainedMessagesManager));
}
+ public async Task ClearMessages()
+ {
+ lock (_messages)
+ {
+ _messages.Clear();
+ }
+
+ using (await _storageAccessLock.EnterAsync().ConfigureAwait(false))
+ {
+ await _eventContainer.RetainedMessagesClearedEvent.InvokeAsync(EventArgs.Empty).ConfigureAwait(false);
+ }
+ }
+
+ public void Dispose()
+ {
+ _storageAccessLock.Dispose();
+ }
+
+ public Task GetMessage(string topic)
+ {
+ lock (_messages)
+ {
+ if (_messages.TryGetValue(topic, out var message))
+ {
+ return Task.FromResult(message);
+ }
+ }
+
+ return Task.FromResult(null);
+ }
+
+ public Task> GetMessages()
+ {
+ lock (_messages)
+ {
+ var result = new List(_messages.Values);
+ return Task.FromResult((IList)result);
+ }
+ }
+
public async Task Start()
{
try
@@ -79,8 +118,7 @@ public async Task UpdateMessage(string clientId, MqttApplicationMessage applicat
}
else
{
- if (existingMessage.QualityOfServiceLevel != applicationMessage.QualityOfServiceLevel ||
- !MqttMemoryHelper.SequenceEqual(existingMessage.Payload, payload))
+ if (existingMessage.QualityOfServiceLevel != applicationMessage.QualityOfServiceLevel || !MqttMemoryHelper.SequenceEqual(existingMessage.Payload, payload))
{
_messages[applicationMessage.Topic] = applicationMessage;
saveIsRequired = true;
@@ -113,39 +151,4 @@ public async Task UpdateMessage(string clientId, MqttApplicationMessage applicat
_logger.Error(exception, "Unhandled exception while handling retained messages.");
}
}
-
- public Task> GetMessages()
- {
- lock (_messages)
- {
- var result = new List(_messages.Values);
- return Task.FromResult((IList)result);
- }
- }
-
- public Task GetMessage(string topic)
- {
- lock (_messages)
- {
- if (_messages.TryGetValue(topic, out var message))
- {
- return Task.FromResult(message);
- }
- }
-
- return Task.FromResult(null);
- }
-
- public async Task ClearMessages()
- {
- lock (_messages)
- {
- _messages.Clear();
- }
-
- using (await _storageAccessLock.EnterAsync().ConfigureAwait(false))
- {
- await _eventContainer.RetainedMessagesClearedEvent.InvokeAsync(EventArgs.Empty).ConfigureAwait(false);
- }
- }
}
\ No newline at end of file
diff --git a/Source/MQTTnet.Server/MQTTnet.Server.csproj b/Source/MQTTnet.Server/MQTTnet.Server.csproj
index b9cd0ca25..32c8ba014 100644
--- a/Source/MQTTnet.Server/MQTTnet.Server.csproj
+++ b/Source/MQTTnet.Server/MQTTnet.Server.csproj
@@ -1,56 +1,19 @@
- net8.0
MQTTnet.Server
MQTTnet.Server
+ true
+
True
- The contributors of MQTTnet
- MQTTnet
true
This is the server implementation of MQTTnet.
- The contributors of MQTTnet
MQTTnet.Server
- false
- false
- true
- true
- snupkg
- Copyright (c) .NET Foundation and Contributors
- https://github.com/dotnet/MQTTnet
- https://github.com/dotnet/MQTTnet.git
- git
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
- en-US
- false
- false
- nuget.png
- true
- true
- LICENSE
- true
- 1591;NETSDK1138;NU1803;NU1901;NU1902
- true
- all
- true
- low
- enable
- disable
- latest-Recommended
- true
-
-
-
-
-
-
-
-
-
diff --git a/Source/MQTTnet.Server/MqttServerFactory.cs b/Source/MQTTnet.Server/MqttServerFactory.cs
index 9971c5a47..35f6bafe7 100644
--- a/Source/MQTTnet.Server/MqttServerFactory.cs
+++ b/Source/MQTTnet.Server/MqttServerFactory.cs
@@ -2,12 +2,14 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Diagnostics.CodeAnalysis;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Server.EnhancedAuthentication;
using MQTTnet.Server.Internal.Adapter;
namespace MQTTnet.Server;
+[SuppressMessage("Performance", "CA1822:Mark members as static")]
public sealed class MqttServerFactory
{
public MqttServerFactory() : this(new MqttNetNullLogger())
diff --git a/Source/MQTTnet.TestApp/AsyncLockTest.cs b/Source/MQTTnet.TestApp/AsyncLockTest.cs
index 65c12826a..594cd8693 100644
--- a/Source/MQTTnet.TestApp/AsyncLockTest.cs
+++ b/Source/MQTTnet.TestApp/AsyncLockTest.cs
@@ -11,7 +11,7 @@ namespace MQTTnet.TestApp;
public sealed class AsyncLockTest
{
- public async Task Run()
+ public static async Task Run()
{
try
{
diff --git a/Source/MQTTnet.TestApp/MQTTnet.TestApp.csproj b/Source/MQTTnet.TestApp/MQTTnet.TestApp.csproj
index 68fc336bf..a4227da09 100644
--- a/Source/MQTTnet.TestApp/MQTTnet.TestApp.csproj
+++ b/Source/MQTTnet.TestApp/MQTTnet.TestApp.csproj
@@ -3,17 +3,7 @@
Exe
Full
- net8.0
false
- false
- false
- true
- 1591;NETSDK1138;NU1803;NU1901;NU1902
- true
- all
- true
- low
- latest-Recommended
diff --git a/Source/MQTTnet.TestApp/MessageThroughputTest.cs b/Source/MQTTnet.TestApp/MessageThroughputTest.cs
index 4a813c9e9..619e92990 100644
--- a/Source/MQTTnet.TestApp/MessageThroughputTest.cs
+++ b/Source/MQTTnet.TestApp/MessageThroughputTest.cs
@@ -14,7 +14,7 @@ namespace MQTTnet.TestApp;
/// the number of messages per second that can be exchanged between publishers and subscriber.
/// Measurements are performed for subscriptions containing no wildcard, a single wildcard or multiple wildcards.
///
-public class MessageThroughputTest
+public sealed class MessageThroughputTest : IDisposable
{
// Change these constants to suit
const int NumPublishers = 5000;
@@ -55,9 +55,9 @@ public async Task Run()
await Setup();
- await Subscribe_to_No_Wildcard_Topics();
- await Subscribe_to_Single_Wildcard_Topics();
- await Subscribe_to_Multi_Wildcard_Topics();
+ await SubscribeToNoWildcardTopics();
+ await SubscribeToSingleWildcardTopics();
+ await SubscribeToMultiWildcardTopics();
Console.WriteLine();
Console.WriteLine("End message throughput test");
@@ -74,7 +74,7 @@ public async Task Run()
public async Task Setup()
{
- new TopicGenerator().Generate(NumPublishers, NumTopicsPerPublisher, out _topicsByPublisher, out _singleWildcardTopicsByPublisher, out _multiWildcardTopicsByPublisher);
+ TopicGenerator.Generate(NumPublishers, NumTopicsPerPublisher, out _topicsByPublisher, out _singleWildcardTopicsByPublisher, out _multiWildcardTopicsByPublisher);
var serverOptions = new MqttServerOptionsBuilder().WithDefaultEndpoint().Build();
var mqttClientFactory = new MqttClientFactory();
@@ -152,7 +152,7 @@ public async Task Cleanup()
///
/// Measure no-wildcard topic subscription message exchange performance
///
- public Task Subscribe_to_No_Wildcard_Topics()
+ public Task SubscribeToNoWildcardTopics()
{
return ProcessMessages(_topicsByPublisher, "no wildcards");
}
@@ -160,7 +160,7 @@ public Task Subscribe_to_No_Wildcard_Topics()
///
/// Measure single-wildcard topic subscription message exchange performance
///
- public Task Subscribe_to_Single_Wildcard_Topics()
+ public Task SubscribeToSingleWildcardTopics()
{
return ProcessMessages(_singleWildcardTopicsByPublisher, "single wildcard");
}
@@ -168,7 +168,7 @@ public Task Subscribe_to_Single_Wildcard_Topics()
///
/// Measure multi-wildcard topic subscription message exchange performance
///
- public Task Subscribe_to_Multi_Wildcard_Topics()
+ public Task SubscribeToMultiWildcardTopics()
{
return ProcessMessages(_multiWildcardTopicsByPublisher, "multi wildcard");
}
@@ -342,4 +342,8 @@ static void ConsoleWriteInfo(string message)
Console.ResetColor();
}
+ public void Dispose()
+ {
+ _cancellationTokenSource.Dispose();
+ }
}
\ No newline at end of file
diff --git a/Source/MQTTnet.TestApp/MqttNetConsoleLogger.cs b/Source/MQTTnet.TestApp/MqttNetConsoleLogger.cs
index 30a153e5a..a97151f11 100644
--- a/Source/MQTTnet.TestApp/MqttNetConsoleLogger.cs
+++ b/Source/MQTTnet.TestApp/MqttNetConsoleLogger.cs
@@ -34,7 +34,9 @@ public static void PrintToConsole(string message, ConsoleColor color)
static void PrintToConsole(object sender, MqttNetLogMessagePublishedEventArgs e)
{
var output = new StringBuilder();
+#pragma warning disable CA1305
output.AppendLine($">> [{e.LogMessage.Timestamp:O}] [{e.LogMessage.ThreadId}] [{e.LogMessage.Source}] [{e.LogMessage.Level}]: {e.LogMessage.Message}");
+#pragma warning restore CA1305
if (e.LogMessage.Exception != null)
{
output.AppendLine(e.LogMessage.Exception.ToString());
diff --git a/Source/MQTTnet.TestApp/PerformanceTest.cs b/Source/MQTTnet.TestApp/PerformanceTest.cs
index 472d2c403..bcf6728e4 100644
--- a/Source/MQTTnet.TestApp/PerformanceTest.cs
+++ b/Source/MQTTnet.TestApp/PerformanceTest.cs
@@ -204,7 +204,7 @@ static MqttApplicationMessage CreateMessage()
};
}
- static Task PublishSingleMessage(IMqttClient client, MqttApplicationMessage applicationMessage, ref int count)
+ static Task PublishSingleMessage(IMqttClient client, MqttApplicationMessage applicationMessage, ref int count)
{
Interlocked.Increment(ref count);
return Task.Run(() => client.PublishAsync(applicationMessage));
diff --git a/Source/MQTTnet.TestApp/Program.cs b/Source/MQTTnet.TestApp/Program.cs
index 1ee1c8fd7..46fb25cf5 100644
--- a/Source/MQTTnet.TestApp/Program.cs
+++ b/Source/MQTTnet.TestApp/Program.cs
@@ -85,7 +85,7 @@ public static void Main()
}
else if (pressedKey.KeyChar == 'f')
{
- Task.Run(new AsyncLockTest().Run);
+ Task.Run(AsyncLockTest.Run);
}
Thread.Sleep(Timeout.Infinite);
diff --git a/Source/MQTTnet.TestApp/PublicBrokerTest.cs b/Source/MQTTnet.TestApp/PublicBrokerTest.cs
index 21c55fdc5..f82797274 100644
--- a/Source/MQTTnet.TestApp/PublicBrokerTest.cs
+++ b/Source/MQTTnet.TestApp/PublicBrokerTest.cs
@@ -157,7 +157,7 @@ static async Task ExecuteTestAsync(string name, MqttClientOptions options)
if (receivedMessage?.Topic != topic || receivedMessage?.ConvertPayloadToString() != "Hello_World")
{
- throw new Exception("Message invalid.");
+ throw new InvalidOperationException("Message invalid.");
}
await client.UnsubscribeAsync(topic).ConfigureAwait(false);
diff --git a/Source/MQTTnet.TestApp/ServerTest.cs b/Source/MQTTnet.TestApp/ServerTest.cs
index ae0e0975c..c22ec2cdb 100644
--- a/Source/MQTTnet.TestApp/ServerTest.cs
+++ b/Source/MQTTnet.TestApp/ServerTest.cs
@@ -129,12 +129,12 @@ public static async Task RunAsync()
mqttServer.InterceptingSubscriptionAsync += e =>
{
- if (e.TopicFilter.Topic.StartsWith("admin/foo/bar") && e.ClientId != "theAdmin")
+ if (e.TopicFilter.Topic.StartsWith("admin/foo/bar", StringComparison.InvariantCulture) && e.ClientId != "theAdmin")
{
e.Response.ReasonCode = MqttSubscribeReasonCode.ImplementationSpecificError;
}
- if (e.TopicFilter.Topic.StartsWith("the/secret/stuff") && e.ClientId != "Imperator")
+ if (e.TopicFilter.Topic.StartsWith("the/secret/stuff", StringComparison.InvariantCulture) && e.ClientId != "Imperator")
{
e.Response.ReasonCode = MqttSubscribeReasonCode.ImplementationSpecificError;
e.CloseConnection = true;
diff --git a/Source/MQTTnet.TestApp/TopicGenerator.cs b/Source/MQTTnet.TestApp/TopicGenerator.cs
index 76ba1a619..5e3e13035 100644
--- a/Source/MQTTnet.TestApp/TopicGenerator.cs
+++ b/Source/MQTTnet.TestApp/TopicGenerator.cs
@@ -6,7 +6,7 @@ namespace MQTTnet.TestApp;
public class TopicGenerator
{
- public void Generate(
+ public static void Generate(
int numPublishers, int numTopicsPerPublisher,
out Dictionary> topicsByPublisher,
out Dictionary> singleWildcardTopicsByPublisher,
@@ -84,14 +84,14 @@ out Dictionary> multiWildcardTopicsByPublisher
}
}
- void AddPublisherTopic(string publisherName, string topic, Dictionary> topicsByPublisher)
+ static void AddPublisherTopic(string publisherName, string topic, Dictionary> topicsByPublisher)
{
- List topicList;
- if (!topicsByPublisher.TryGetValue(publisherName, out topicList))
+ if (!topicsByPublisher.TryGetValue(publisherName, out var topicList))
{
topicList = new List();
topicsByPublisher.Add(publisherName, topicList);
}
+
topicList.Add(topic);
}
}
\ No newline at end of file
diff --git a/Source/MQTTnet.Tests/ASP/MqttConnectionContextTest.cs b/Source/MQTTnet.Tests/ASP/MqttConnectionContextTest.cs
index b067a236f..6f58952d3 100644
--- a/Source/MQTTnet.Tests/ASP/MqttConnectionContextTest.cs
+++ b/Source/MQTTnet.Tests/ASP/MqttConnectionContextTest.cs
@@ -119,9 +119,11 @@ public async Task TestReceivePacketAsyncThrowsWhenReaderCompleted()
await Assert.ThrowsExactlyAsync(() => ctx.ReceivePacketAsync(CancellationToken.None)).ConfigureAwait(false);
}
- class Startup
+ sealed class Startup
{
+#pragma warning disable CA1822
public void Configure(IApplicationBuilder app)
+#pragma warning restore CA1822
{
}
}
diff --git a/Source/MQTTnet.Tests/BaseTestClass.cs b/Source/MQTTnet.Tests/BaseTestClass.cs
index b70881575..198421c25 100644
--- a/Source/MQTTnet.Tests/BaseTestClass.cs
+++ b/Source/MQTTnet.Tests/BaseTestClass.cs
@@ -20,12 +20,12 @@ protected TestEnvironment CreateTestEnvironment(
return new TestEnvironment(TestContext, protocolVersion, trackUnobservedTaskException);
}
- protected Task LongTestDelay()
+ public static Task LongTestDelay()
{
return Task.Delay(TimeSpan.FromSeconds(1));
}
- protected Task MediumTestDelay()
+ public static Task MediumTestDelay()
{
return Task.Delay(TimeSpan.FromSeconds(0.5));
}
diff --git a/Source/MQTTnet.Tests/Clients/LowLevelMqttClient/LowLevelMqttClient_Tests.cs b/Source/MQTTnet.Tests/Clients/LowLevelMqttClient/LowLevelMqttClient_Tests.cs
index 907f97b7e..18fdafa88 100644
--- a/Source/MQTTnet.Tests/Clients/LowLevelMqttClient/LowLevelMqttClient_Tests.cs
+++ b/Source/MQTTnet.Tests/Clients/LowLevelMqttClient/LowLevelMqttClient_Tests.cs
@@ -188,7 +188,7 @@ await client.SendAsync(
return await client.ReceiveAsync(CancellationToken.None) as MqttConnAckPacket;
}
- async Task Subscribe(ILowLevelMqttClient client, string topic)
+ static async Task Subscribe(ILowLevelMqttClient client, string topic)
{
await client.SendAsync(
new MqttSubscribePacket
diff --git a/Source/MQTTnet.Tests/Clients/MqttClient/MqttClient_Connection_Tests.cs b/Source/MQTTnet.Tests/Clients/MqttClient/MqttClient_Connection_Tests.cs
index 24bb6b1b0..603762716 100644
--- a/Source/MQTTnet.Tests/Clients/MqttClient/MqttClient_Connection_Tests.cs
+++ b/Source/MQTTnet.Tests/Clients/MqttClient/MqttClient_Connection_Tests.cs
@@ -73,7 +73,7 @@ public async Task ConnectTimeout_Throws_Exception()
catch (Exception exception)
{
Assert.IsNotNull(exception);
- Assert.IsInstanceOfType(exception, typeof(MqttCommunicationException));
+ Assert.IsInstanceOfType(exception);
}
await LongTestDelay(); // disconnected handler is called async
@@ -161,7 +161,7 @@ public async Task Disconnect_Clean_With_User_Properties()
Assert.AreEqual("test_value", eventArgs.UserProperties[0].Value);
}
- class TestClientKerberosAuthenticationHandler : IMqttEnhancedAuthenticationHandler
+ sealed class TestClientKerberosAuthenticationHandler : IMqttEnhancedAuthenticationHandler
{
public async Task HandleEnhancedAuthenticationAsync(MqttEnhancedAuthenticationEventArgs eventArgs)
{
diff --git a/Source/MQTTnet.Tests/Clients/MqttClient/MqttClient_Tests.cs b/Source/MQTTnet.Tests/Clients/MqttClient/MqttClient_Tests.cs
index 193984608..6a085e867 100644
--- a/Source/MQTTnet.Tests/Clients/MqttClient/MqttClient_Tests.cs
+++ b/Source/MQTTnet.Tests/Clients/MqttClient/MqttClient_Tests.cs
@@ -6,6 +6,7 @@
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Globalization;
using System.Linq;
using System.Net.Sockets;
using System.Text;
@@ -122,8 +123,8 @@ public async Task Disconnect_Event_Contains_Exception()
await Task.Delay(500);
Assert.IsNotNull(ex);
- Assert.IsInstanceOfType(ex, typeof(MqttCommunicationException));
- Assert.IsInstanceOfType(ex.InnerException, typeof(SocketException));
+ Assert.IsInstanceOfType(ex);
+ Assert.IsInstanceOfType(ex.InnerException);
}
[TestMethod]
@@ -245,8 +246,8 @@ public async Task Invalid_Connect_Throws_Exception()
catch (Exception exception)
{
Assert.IsNotNull(exception);
- Assert.IsInstanceOfType(exception, typeof(MqttCommunicationException));
- Assert.IsInstanceOfType(exception.InnerException, typeof(SocketException));
+ Assert.IsInstanceOfType(exception);
+ Assert.IsInstanceOfType(exception.InnerException);
}
}
@@ -355,7 +356,7 @@ public async Task Preserve_Message_Order()
async Task Handler1(MqttApplicationMessageReceivedEventArgs eventArgs)
{
- var value = int.Parse(eventArgs.ApplicationMessage.ConvertPayloadToString());
+ var value = int.Parse(eventArgs.ApplicationMessage.ConvertPayloadToString(), CultureInfo.InvariantCulture);
await Task.Delay(value);
lock (receivedValues)
@@ -369,7 +370,7 @@ async Task Handler1(MqttApplicationMessageReceivedEventArgs eventArgs)
var client2 = await testEnvironment.ConnectClient();
for (var i = MessagesCount; i > 0; i--)
{
- await client2.PublishStringAsync("x", i.ToString());
+ await client2.PublishStringAsync("x", i.ToString(CultureInfo.InvariantCulture));
}
await Task.Delay(5000);
@@ -401,7 +402,7 @@ public async Task Preserve_Message_Order_With_Delayed_Acknowledgement()
var client2 = await testEnvironment.ConnectClient();
for (var i = MessagesCount; i > 0; i--)
{
- await client2.PublishStringAsync("x", i.ToString(), MqttQualityOfServiceLevel.ExactlyOnce);
+ await client2.PublishStringAsync("x", i.ToString(CultureInfo.InvariantCulture), MqttQualityOfServiceLevel.ExactlyOnce);
}
await Task.Delay(5000);
@@ -415,7 +416,7 @@ public async Task Preserve_Message_Order_With_Delayed_Acknowledgement()
Task Handler1(MqttApplicationMessageReceivedEventArgs eventArgs)
{
- var value = int.Parse(eventArgs.ApplicationMessage.ConvertPayloadToString());
+ var value = int.Parse(eventArgs.ApplicationMessage.ConvertPayloadToString(), CultureInfo.InvariantCulture);
eventArgs.AutoAcknowledge = false;
Task.Delay(value).ContinueWith(_ => eventArgs.AcknowledgeAsync(CancellationToken.None));
diff --git a/Source/MQTTnet.Tests/Extensions/Rpc_Tests.cs b/Source/MQTTnet.Tests/Extensions/Rpc_Tests.cs
index ca39646f1..acf9c9169 100644
--- a/Source/MQTTnet.Tests/Extensions/Rpc_Tests.cs
+++ b/Source/MQTTnet.Tests/Extensions/Rpc_Tests.cs
@@ -220,7 +220,7 @@ async Task Execute_Success_MQTT_V5(MqttQualityOfServiceLevel qosLevel)
Assert.AreEqual("pong", Encoding.UTF8.GetString(response));
}
- class TestTopicStrategy : IMqttRpcClientTopicGenerationStrategy
+ sealed class TestTopicStrategy : IMqttRpcClientTopicGenerationStrategy
{
public MqttRpcTopicPair CreateRpcTopics(TopicGenerationContext context)
{
@@ -232,7 +232,7 @@ public MqttRpcTopicPair CreateRpcTopics(TopicGenerationContext context)
}
}
- class TestParametersTopicGenerationStrategy : IMqttRpcClientTopicGenerationStrategy
+ sealed class TestParametersTopicGenerationStrategy : IMqttRpcClientTopicGenerationStrategy
{
internal const string ExpectedParamName = "test_param_name";
diff --git a/Source/MQTTnet.Tests/Formatter/MqttBufferReader_Tests.cs b/Source/MQTTnet.Tests/Formatter/MqttBufferReader_Tests.cs
index 0ced1b0bf..d449d4761 100644
--- a/Source/MQTTnet.Tests/Formatter/MqttBufferReader_Tests.cs
+++ b/Source/MQTTnet.Tests/Formatter/MqttBufferReader_Tests.cs
@@ -287,7 +287,7 @@ public void Report_Correct_Length_For_Partial_Start_Buffer()
// Helper class to build up a reference to elements of various types in a buffer
- class ElementReference
+ sealed class ElementReference
{
public enum BufferElementType
{
diff --git a/Source/MQTTnet.Tests/Formatter/MqttPacketSerialization_V3_Binary_Tests.cs b/Source/MQTTnet.Tests/Formatter/MqttPacketSerialization_V3_Binary_Tests.cs
index a83404b51..e9c950622 100644
--- a/Source/MQTTnet.Tests/Formatter/MqttPacketSerialization_V3_Binary_Tests.cs
+++ b/Source/MQTTnet.Tests/Formatter/MqttPacketSerialization_V3_Binary_Tests.cs
@@ -551,7 +551,7 @@ public void SerializeV311_MqttUnsubscribePacket()
}
- void DeserializeAndCompare(MqttPacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
+ static void DeserializeAndCompare(MqttPacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
{
var writer = WriterFactory();
diff --git a/Source/MQTTnet.Tests/Internal/MqttPacketBus_Tests.cs b/Source/MQTTnet.Tests/Internal/MqttPacketBus_Tests.cs
index 9152682dc..dfd78bc2e 100644
--- a/Source/MQTTnet.Tests/Internal/MqttPacketBus_Tests.cs
+++ b/Source/MQTTnet.Tests/Internal/MqttPacketBus_Tests.cs
@@ -35,15 +35,15 @@ public void Alternate_Priorities()
Assert.AreEqual(9, bus.TotalItemsCount);
- Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet, typeof(MqttPublishPacket));
- Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet, typeof(MqttSubAckPacket));
- Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet, typeof(MqttPingRespPacket));
- Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet, typeof(MqttPublishPacket));
- Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet, typeof(MqttSubAckPacket));
- Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet, typeof(MqttPingRespPacket));
- Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet, typeof(MqttPublishPacket));
- Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet, typeof(MqttSubAckPacket));
- Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet, typeof(MqttPingRespPacket));
+ Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet);
+ Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet);
+ Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet);
+ Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet);
+ Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet);
+ Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet);
+ Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet);
+ Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet);
+ Assert.IsInstanceOfType(bus.DequeueItemAsync(CancellationToken.None).Result.Packet);
Assert.AreEqual(0, bus.TotalItemsCount);
}
diff --git a/Source/MQTTnet.Tests/MQTTnet.Tests.csproj b/Source/MQTTnet.Tests/MQTTnet.Tests.csproj
index 419c0493b..845429545 100644
--- a/Source/MQTTnet.Tests/MQTTnet.Tests.csproj
+++ b/Source/MQTTnet.Tests/MQTTnet.Tests.csproj
@@ -3,19 +3,10 @@
Exe
- net8.0
false
- false
- false
- true
- 1591;NETSDK1138;NU1803;NU1901;NU1902
- true
- all
- true
- low
- latest-Recommended
default
disable
+ $(NoWarn);CA1707
@@ -23,7 +14,6 @@
-
diff --git a/Source/MQTTnet.Tests/Mockups/MemoryMqttChannel.cs b/Source/MQTTnet.Tests/Mockups/MemoryMqttChannel.cs
index 1c9e32693..6093c7882 100644
--- a/Source/MQTTnet.Tests/Mockups/MemoryMqttChannel.cs
+++ b/Source/MQTTnet.Tests/Mockups/MemoryMqttChannel.cs
@@ -31,7 +31,7 @@ public MemoryMqttChannel(byte[] buffer)
public EndPoint LocalEndPoint { get; set; }
- public bool IsSecureConnection { get; } = false;
+ public bool IsSecureConnection { get; }
public X509Certificate2 ClientCertificate { get; set; }
@@ -60,5 +60,6 @@ public async Task WriteAsync(ReadOnlySequence buffer, bool isEndOfPacket,
public void Dispose()
{
+ _stream.Dispose();
}
}
\ No newline at end of file
diff --git a/Source/MQTTnet.Tests/Mockups/TestEnvironment.cs b/Source/MQTTnet.Tests/Mockups/TestEnvironment.cs
index c0083f93b..23cd8f647 100644
--- a/Source/MQTTnet.Tests/Mockups/TestEnvironment.cs
+++ b/Source/MQTTnet.Tests/Mockups/TestEnvironment.cs
@@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -182,7 +181,9 @@ public async Task ConnectRpcClient(MqttRpcClientOptions options)
return new MqttRpcClient(await ConnectClient(), options);
}
+#pragma warning disable CA1822
public TestApplicationMessageReceivedHandler CreateApplicationMessageHandler(IMqttClient mqttClient)
+#pragma warning restore CA1822
{
return new TestApplicationMessageReceivedHandler(mqttClient);
}
@@ -199,7 +200,7 @@ public IMqttClient CreateClient()
{
var clientOptions = e.ClientOptions;
var existingClientId = clientOptions.ClientId;
- if (existingClientId != null && !existingClientId.StartsWith(TestContext.TestName))
+ if (existingClientId != null && !existingClientId.StartsWith(TestContext.TestName, StringComparison.InvariantCulture))
{
clientOptions.ClientId = TestContext.TestName + "_" + existingClientId;
}
@@ -257,7 +258,7 @@ public MqttServer CreateServer(MqttServerOptions options)
if (TestContext != null)
{
// Null is used when the client id is assigned from the server!
- if (!string.IsNullOrEmpty(e.ClientId) && !e.ClientId.StartsWith(TestContext.TestName))
+ if (!string.IsNullOrEmpty(e.ClientId) && !e.ClientId.StartsWith(TestContext.TestName, StringComparison.InvariantCulture))
{
TrackException(new InvalidOperationException($"Invalid client ID used ({e.ClientId}). It must start with UnitTest name."));
e.ReasonCode = MqttConnectReasonCode.ClientIdentifierNotValid;
@@ -326,10 +327,10 @@ public void Dispose()
GC.WaitForFullGCComplete();
GC.WaitForPendingFinalizers();
- if (_exceptions.Any())
+ if (_exceptions.Count > 0)
{
// ReSharper disable once ThrowExceptionInUnexpectedLocation
- throw new Exception($"{_exceptions.Count} exceptions tracked.\r\n" + string.Join(Environment.NewLine, _exceptions));
+ throw new InvalidOperationException($"{_exceptions.Count} exceptions tracked.\r\n" + string.Join(Environment.NewLine, _exceptions));
}
}
finally
@@ -387,7 +388,7 @@ public void ThrowIfLogErrors()
{
var message = $"Server had {_serverErrors.Count} errors (${string.Join(Environment.NewLine, _serverErrors)}).";
Console.WriteLine(message);
- throw new Exception(message);
+ throw new InvalidOperationException(message);
}
}
}
@@ -400,7 +401,7 @@ public void ThrowIfLogErrors()
{
var message = $"Client(s) had {_clientErrors.Count} errors (${string.Join(Environment.NewLine, _clientErrors)})";
Console.WriteLine(message);
- throw new Exception(message);
+ throw new InvalidOperationException(message);
}
}
}
diff --git a/Source/MQTTnet.Tests/Mockups/TestLogger.cs b/Source/MQTTnet.Tests/Mockups/TestLogger.cs
index ab2d535cf..7cfe1d98f 100644
--- a/Source/MQTTnet.Tests/Mockups/TestLogger.cs
+++ b/Source/MQTTnet.Tests/Mockups/TestLogger.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Globalization;
using MQTTnet.Diagnostics.Logger;
namespace MQTTnet.Tests.Mockups;
@@ -13,12 +14,12 @@ public sealed class TestLogger : IMqttNetLogger
public bool IsEnabled { get; } = true;
- public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception)
+ public void Publish(MqttNetLogLevel level, string source, string message, object[] parameters, Exception exception)
{
LogMessagePublished?.Invoke(this, new MqttNetLogMessagePublishedEventArgs(new MqttNetLogMessage
{
- Level = logLevel,
- Message = string.Format(message, parameters),
+ Level = level,
+ Message = string.Format(CultureInfo.InvariantCulture, message, parameters),
Exception = exception
}));
}
diff --git a/Source/MQTTnet.Tests/MqttTcpChannel_Tests.cs b/Source/MQTTnet.Tests/MqttTcpChannel_Tests.cs
index bc65a0c73..d0e468183 100644
--- a/Source/MQTTnet.Tests/MqttTcpChannel_Tests.cs
+++ b/Source/MQTTnet.Tests/MqttTcpChannel_Tests.cs
@@ -71,7 +71,7 @@ public async Task Dispose_Channel_While_Used()
}
catch (Exception exception)
{
- Assert.IsInstanceOfType(exception, typeof(SocketException));
+ Assert.IsInstanceOfType(exception);
Assert.AreEqual(SocketError.OperationAborted, ((SocketException)exception).SocketErrorCode);
}
}
diff --git a/Source/MQTTnet.Tests/RoundtripTime_Tests.cs b/Source/MQTTnet.Tests/RoundtripTime_Tests.cs
index d3d99f0e8..36ac91fd9 100644
--- a/Source/MQTTnet.Tests/RoundtripTime_Tests.cs
+++ b/Source/MQTTnet.Tests/RoundtripTime_Tests.cs
@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Globalization;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MQTTnet.Internal;
@@ -45,7 +46,7 @@ public async Task Round_Trip_Time()
for (var i = 0; i < 100; i++)
{
response = new TaskCompletionSource();
- await senderClient.PublishStringAsync("test", DateTime.UtcNow.Ticks.ToString());
+ await senderClient.PublishStringAsync("test", DateTime.UtcNow.Ticks.ToString(CultureInfo.InvariantCulture));
if (!response.Task.Wait(TimeSpan.FromSeconds(5)))
{
throw new TimeoutException();
diff --git a/Source/MQTTnet.Tests/Server/General.cs b/Source/MQTTnet.Tests/Server/General.cs
index 429054264..12955cf99 100644
--- a/Source/MQTTnet.Tests/Server/General.cs
+++ b/Source/MQTTnet.Tests/Server/General.cs
@@ -350,7 +350,7 @@ public async Task Intercept_Message()
var isIntercepted = false;
c2.ApplicationMessageReceivedAsync += e =>
{
- isIntercepted = string.Compare("extended", Encoding.UTF8.GetString(e.ApplicationMessage.Payload), StringComparison.Ordinal) == 0;
+ isIntercepted = string.Equals("extended", Encoding.UTF8.GetString(e.ApplicationMessage.Payload), StringComparison.Ordinal);
return CompletedTask.Instance;
};
diff --git a/Source/MQTTnet.Tests/Server/HotSwapCerts_Tests.cs b/Source/MQTTnet.Tests/Server/HotSwapCerts_Tests.cs
index 74b695515..71195afa3 100644
--- a/Source/MQTTnet.Tests/Server/HotSwapCerts_Tests.cs
+++ b/Source/MQTTnet.Tests/Server/HotSwapCerts_Tests.cs
@@ -295,10 +295,10 @@ public Task StartServer()
}
}
- class HotSwappableClientCertProvider : IMqttClientCertificatesProvider, IDisposable
+ sealed class HotSwappableClientCertProvider : IMqttClientCertificatesProvider, IDisposable
{
X509Certificate2Collection _certificates;
- ConcurrentBag _serverCerts = new ConcurrentBag();
+ ConcurrentBag _serverCerts = new();
public HotSwappableClientCertProvider()
{
diff --git a/Source/MQTTnet.Tests/Server/MqttSubscriptionsManager_Tests.cs b/Source/MQTTnet.Tests/Server/MqttSubscriptionsManager_Tests.cs
index 6f3c9ebc5..c8291cddb 100644
--- a/Source/MQTTnet.Tests/Server/MqttSubscriptionsManager_Tests.cs
+++ b/Source/MQTTnet.Tests/Server/MqttSubscriptionsManager_Tests.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
@@ -16,10 +17,15 @@ namespace MQTTnet.Tests.Server;
// ReSharper disable InconsistentNaming
[TestClass]
-public sealed class MqttSubscriptionsManager_Tests : BaseTestClass
+public sealed class MqttSubscriptionsManager_Tests : BaseTestClass, IDisposable
{
MqttClientSubscriptionsManager _subscriptionsManager;
+ public void Dispose()
+ {
+ _subscriptionsManager?.Dispose();
+ }
+
[TestMethod]
public async Task MqttSubscriptionsManager_SubscribeAndUnsubscribeSingle()
{
@@ -46,7 +52,7 @@ public async Task MqttSubscriptionsManager_SubscribeDifferentQoSSuccess()
{
TopicFilters =
[
- new() { Topic = "A/B/C", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce }
+ new MqttTopicFilter { Topic = "A/B/C", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce }
]
};
@@ -178,24 +184,27 @@ public async Task MqttSubscriptionsManager_SubscribeWildcard5()
CheckIsNotSubscribed("house/2/room/bed");
}
- async Task SubscribeToTopic(string topic)
+ [TestInitialize]
+ public void TestInitialize()
{
- var sp = new MqttSubscribePacket
- {
- TopicFilters =
- [
- new MqttTopicFilter { Topic = topic, QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce }
- ]
- };
+ var logger = new TestLogger();
+ var options = new MqttServerOptions();
+ var retainedMessagesManager = new MqttRetainedMessagesManager(new MqttServerEventContainer(), logger);
+ var eventContainer = new MqttServerEventContainer();
+ var clientSessionManager = new MqttClientSessionsManager(options, retainedMessagesManager, eventContainer, logger);
- await _subscriptionsManager.Subscribe(sp, CancellationToken.None);
- }
+ var session = new MqttSession(
+ new MqttConnectPacket
+ {
+ ClientId = ""
+ },
+ new ConcurrentDictionary
\ No newline at end of file