diff --git a/.editorconfig b/.editorconfig
index 4b09c85d..bf2e42f8 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -186,6 +186,15 @@ csharp_style_unused_value_expression_statement_preference = discard_variable:sug
dotnet_diagnostic.IDE0058.severity = suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
dotnet_diagnostic.IDE0059.severity = suggestion
+dotnet_diagnostic.IDE0002.severity = none
+dotnet_diagnostic.IDE0010.severity = none
+dotnet_diagnostic.IDE0021.severity = none
+dotnet_diagnostic.IDE0028.severity = none
+dotnet_diagnostic.IDE0049.severity = none
+dotnet_diagnostic.IDE0053.severity = none
+dotnet_diagnostic.IDE0090.severity = none
+dotnet_diagnostic.IDE0290.severity = none
+dotnet_diagnostic.SA1508.severity = none
##########################################
# Formatting Rules
diff --git a/.vscode/settings.json b/.vscode/settings.json
index feb9c5c3..5fea68f3 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -4,6 +4,8 @@
],
"cSpell.words": [
"CONNACK",
+ "hivemq",
+ "hivemqtt",
"PUBACK",
"PUBCOMP",
"PUBREC",
diff --git a/Examples/HiveMQtt-CLI/HiveMQtt-CLI/HiveMQtt-CLI.csproj b/Examples/HiveMQtt-CLI/HiveMQtt-CLI/HiveMQtt-CLI.csproj
index ad428fd3..48ab58d9 100644
--- a/Examples/HiveMQtt-CLI/HiveMQtt-CLI/HiveMQtt-CLI.csproj
+++ b/Examples/HiveMQtt-CLI/HiveMQtt-CLI/HiveMQtt-CLI.csproj
@@ -2,7 +2,7 @@
Exe
- net7.0
+ net6.0
HiveMQtt_CLI
enable
enable
diff --git a/Examples/Reconnect/.vscode/launch.json b/Examples/Reconnect/.vscode/launch.json
index e1dfc16d..02b00af0 100644
--- a/Examples/Reconnect/.vscode/launch.json
+++ b/Examples/Reconnect/.vscode/launch.json
@@ -10,7 +10,7 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
- "program": "${workspaceFolder}/bin/Debug/net7.0/Reconnect.dll",
+ "program": "${workspaceFolder}/bin/Debug/net6.0/Reconnect.dll",
"args": [],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
diff --git a/Examples/Reconnect/NLog.config b/Examples/Reconnect/NLog.config
new file mode 100644
index 00000000..545f1e8a
--- /dev/null
+++ b/Examples/Reconnect/NLog.config
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Examples/Reconnect/Program.cs b/Examples/Reconnect/Program.cs
index 4d9d38ec..828b218c 100644
--- a/Examples/Reconnect/Program.cs
+++ b/Examples/Reconnect/Program.cs
@@ -1,12 +1,16 @@
using HiveMQtt.Client;
+using HiveMQtt.Client.Exceptions;
using HiveMQtt.Client.Options;
using System.Text.Json;
+using System.Diagnostics;
var topic = "hivemqtt/waiting/game";
-var options = new HiveMQClientOptions();
-options.Host = "127.0.0.1";
-options.Port = 1883;
+var options = new HiveMQClientOptions
+{
+ Host = "127.0.0.1",
+ Port = 1883,
+};
var client = new HiveMQClient(options);
@@ -74,12 +78,12 @@
break;
}
}
- catch (Exception ex)
+ catch (HiveMQttClientException ex)
{
- Console.WriteLine($"--> Failed to connect: {ex.Message}");
+ Console.WriteLine($"--> Failed to reconnect: {ex.Message}");
// Double the delay with each failed retry to a maximum
- delay = Math.Min(delay * 2, 10000);
+ delay = Math.Min(delay * 2, 15000);
Console.WriteLine($"--> Will delay for {delay / 1000} seconds until next try.");
}
}
@@ -123,7 +127,6 @@
})
).ConfigureAwait(false);
-
while (true)
{
await Task.Delay(2000).ConfigureAwait(false);
diff --git a/Examples/Reconnect/Reconnect.csproj b/Examples/Reconnect/Reconnect.csproj
index 0e7e705f..6a80f800 100644
--- a/Examples/Reconnect/Reconnect.csproj
+++ b/Examples/Reconnect/Reconnect.csproj
@@ -2,7 +2,7 @@
Exe
- net7.0
+ net6.0
enable
enable
@@ -13,8 +13,16 @@
+
+ 4
+
-
+
+
+
+ PreserveNewest
+
+
diff --git a/Source/HiveMQtt/Client/HiveMQClient.cs b/Source/HiveMQtt/Client/HiveMQClient.cs
index 9855980e..ed4f0407 100644
--- a/Source/HiveMQtt/Client/HiveMQClient.cs
+++ b/Source/HiveMQtt/Client/HiveMQClient.cs
@@ -42,6 +42,7 @@ public HiveMQClient(HiveMQClientOptions? options = null)
{
options ??= new HiveMQClientOptions();
this.Options = options;
+ this.cancellationSource = new CancellationTokenSource();
}
///
diff --git a/Source/HiveMQtt/Client/HiveMQClientEvents.cs b/Source/HiveMQtt/Client/HiveMQClientEvents.cs
index ed7c5bc8..5a8b7847 100644
--- a/Source/HiveMQtt/Client/HiveMQClientEvents.cs
+++ b/Source/HiveMQtt/Client/HiveMQClientEvents.cs
@@ -16,7 +16,6 @@
namespace HiveMQtt.Client;
using System;
-using System.Diagnostics;
using HiveMQtt.Client.Events;
using HiveMQtt.Client.Options;
using HiveMQtt.Client.Results;
diff --git a/Source/HiveMQtt/Client/HiveMQClientSocket.cs b/Source/HiveMQtt/Client/HiveMQClientSocket.cs
index d3ec55df..4ef2d348 100644
--- a/Source/HiveMQtt/Client/HiveMQClientSocket.cs
+++ b/Source/HiveMQtt/Client/HiveMQClientSocket.cs
@@ -29,11 +29,11 @@ namespace HiveMQtt.Client;
///
public partial class HiveMQClient : IDisposable, IHiveMQClient
{
+ private readonly CancellationTokenSource cancellationSource;
private Socket? socket;
private Stream? stream;
private PipeReader? reader;
private PipeWriter? writer;
- private CancellationTokenSource cancellationSource;
private CancellationToken outFlowCancellationToken;
private CancellationToken infoFlowCancellationToken;
@@ -131,7 +131,6 @@ internal async Task ConnectSocketAsync()
this.writer = PipeWriter.Create(this.stream);
// Setup the cancellation tokens
- this.cancellationSource = new CancellationTokenSource();
this.outFlowCancellationToken = this.cancellationSource.Token;
this.infoFlowCancellationToken = this.cancellationSource.Token;
diff --git a/Source/HiveMQtt/Client/HiveMQClientTrafficProcessor.cs b/Source/HiveMQtt/Client/HiveMQClientTrafficProcessor.cs
index c985db44..f8f72def 100644
--- a/Source/HiveMQtt/Client/HiveMQClientTrafficProcessor.cs
+++ b/Source/HiveMQtt/Client/HiveMQClientTrafficProcessor.cs
@@ -207,7 +207,7 @@ private Task TrafficInflowProcessorAsync(CancellationToken cancellationTok
if (readResult.IsCompleted)
{
// This is an unexpected exit and may be due to a network failure.
- Logger.Trace("TrafficInflowProcessor IsCompleted: end of the streamx");
+ Logger.Trace("TrafficInflowProcessor IsCompleted: end of the stream");
if (this.connectState == ConnectState.Connected)
{
@@ -220,6 +220,7 @@ private Task TrafficInflowProcessorAsync(CancellationToken cancellationTok
this.cancellationSource.Cancel();
return false;
}
+
return true;
}
@@ -308,7 +309,7 @@ private Task TrafficInflowProcessorAsync(CancellationToken cancellationTok
///
/// Handle an incoming Publish packet.
///
- ///
+ /// The received publish packet.
internal void HandleIncomingPublishPacket(PublishPacket publishPacket)
{
Logger.Trace("<-- Publish");
@@ -339,8 +340,8 @@ internal void HandleIncomingPublishPacket(PublishPacket publishPacket)
///
/// Handle an incoming ConnAck packet.
///
- ///
- ///
+ /// The received PubAck packet.
+ /// Raised if the packet identifier is unknown.
internal void HandleIncomingPubAckPacket(PubAckPacket pubAckPacket)
{
Logger.Trace("<-- PubAck");
@@ -362,7 +363,7 @@ internal void HandleIncomingPubAckPacket(PubAckPacket pubAckPacket)
///
/// Handle an incoming PubRec packet.
///
- ///
+ /// The received PubRec packet.
internal void HandleIncomingPubRecPacket(PubRecPacket pubRecPacket)
{
Logger.Trace("<-- PubRec");
@@ -394,7 +395,7 @@ internal void HandleIncomingPubRecPacket(PubRecPacket pubRecPacket)
///
/// Handle an incoming PubRel packet.
///
- ///
+ /// The received PubRel packet.
internal void HandleIncomingPubRelPacket(PubRelPacket pubRelPacket)
{
Logger.Trace("<-- PubRel");
@@ -417,8 +418,8 @@ internal void HandleIncomingPubRelPacket(PubRelPacket pubRelPacket)
///
/// Handle an incoming PubComp packet.
///
- ///
- ///
+ /// The received PubComp packet.
+ /// Raised if the packet identifier is unknown.
internal void HandleIncomingPubCompPacket(PubCompPacket pubCompPacket)
{
Logger.Trace("<-- PubComp");
@@ -433,10 +434,10 @@ internal void HandleIncomingPubCompPacket(PubCompPacket pubCompPacket)
///
/// Write a buffer to the stream.
///
- ///
- ///
- ///
- ///
+ /// The buffer to write.
+ /// The cancellation token.
+ /// A FlushResult wrapped in a ValueTask.
+ /// Raised if the writer is null.
internal ValueTask WriteAsync(ReadOnlyMemory source, CancellationToken cancellationToken = default)
{
if (this.writer is null)
@@ -450,9 +451,9 @@ internal ValueTask WriteAsync(ReadOnlyMemory source, Cancella
///
/// Read a buffer from the stream.
///
- ///
- ///
- ///
+ /// The cancellation token.
+ /// A ReadResult wrapped in a ValueTask.
+ /// Raised if the reader is null.
internal ValueTask ReadAsync(CancellationToken cancellationToken = default)
{
if (this.reader is null)
diff --git a/Source/HiveMQtt/Client/HiveMQClientUtil.cs b/Source/HiveMQtt/Client/HiveMQClientUtil.cs
index 6cf1ac9f..74882396 100644
--- a/Source/HiveMQtt/Client/HiveMQClientUtil.cs
+++ b/Source/HiveMQtt/Client/HiveMQClientUtil.cs
@@ -18,8 +18,8 @@ namespace HiveMQtt.Client;
///
public partial class HiveMQClient : IDisposable, IHiveMQClient
{
- private bool disposed = false;
- private int lastPacketId = 0;
+ private bool disposed;
+ private int lastPacketId;
///
/// https://learn.microsoft.com/en-us/dotnet/api/system.idisposable?view=net-6.0.
diff --git a/Source/HiveMQtt/Client/Results/UnsubscribeResult.cs b/Source/HiveMQtt/Client/Results/UnsubscribeResult.cs
index 78800096..6f6e7208 100644
--- a/Source/HiveMQtt/Client/Results/UnsubscribeResult.cs
+++ b/Source/HiveMQtt/Client/Results/UnsubscribeResult.cs
@@ -19,7 +19,6 @@ namespace HiveMQtt.Client.Results;
public class UnsubscribeResult
{
- // FIXME: List of subscriptions with their unsubscribe reason codes
public UnsubscribeResult()
{
this.Subscriptions = new List();
diff --git a/Source/HiveMQtt/HiveMQtt.sln b/Source/HiveMQtt/HiveMQtt.sln
index b2dd6cf5..b8545607 100644
--- a/Source/HiveMQtt/HiveMQtt.sln
+++ b/Source/HiveMQtt/HiveMQtt.sln
@@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HiveMQtt", "HiveMQtt.csproj
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HiveMQtt-CLI", "..\..\Examples\HiveMQtt-CLI\HiveMQtt-CLI\HiveMQtt-CLI.csproj", "{B7404198-178C-43C5-9136-4BF25D23EC7E}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reconnect", "..\..\Examples\Reconnect\Reconnect.csproj", "{FE0AD218-169C-4DE6-ADBE-0B55695620B4}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +23,10 @@ Global
{B7404198-178C-43C5-9136-4BF25D23EC7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B7404198-178C-43C5-9136-4BF25D23EC7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7404198-178C-43C5-9136-4BF25D23EC7E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FE0AD218-169C-4DE6-ADBE-0B55695620B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FE0AD218-169C-4DE6-ADBE-0B55695620B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FE0AD218-169C-4DE6-ADBE-0B55695620B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FE0AD218-169C-4DE6-ADBE-0B55695620B4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Source/HiveMQtt/Properties/AssemblyInfo.cs b/Source/HiveMQtt/Properties/AssemblyInfo.cs
index e60eeec6..58758516 100644
--- a/Source/HiveMQtt/Properties/AssemblyInfo.cs
+++ b/Source/HiveMQtt/Properties/AssemblyInfo.cs
@@ -1,5 +1,5 @@
using System.Runtime.CompilerServices;
-[assembly:InternalsVisibleTo("HiveMQtt.Test")]
+[assembly: InternalsVisibleTo("HiveMQtt.Test")]
[assembly: CLSCompliant(true)]
diff --git a/Tests/HiveMQtt.Test/HiveMQClient/HiveMQClientConnectTest.cs b/Tests/HiveMQtt.Test/HiveMQClient/HiveMQClientConnectTest.cs
index 3efb0538..0eb2c755 100644
--- a/Tests/HiveMQtt.Test/HiveMQClient/HiveMQClientConnectTest.cs
+++ b/Tests/HiveMQtt.Test/HiveMQClient/HiveMQClientConnectTest.cs
@@ -1,5 +1,6 @@
namespace HiveMQtt.Test.HiveMQClient;
+using System.Globalization;
using System.Threading.Tasks;
using HiveMQtt.Client;
using HiveMQtt.Client.Events;
@@ -161,7 +162,7 @@ public async Task Test_AfterDisconnectEvent_Async()
// Assert that all Events were called
Assert.True(client.LocalStore.ContainsKey("AfterDisconnectHandlerCalled"));
Assert.True(client.LocalStore.ContainsKey("AfterDisconnectHandlerCalledCount"));
- Assert.Equal(client.LocalStore["AfterDisconnectHandlerCalledCount"], "1");
+ Assert.Equal("1", client.LocalStore["AfterDisconnectHandlerCalledCount"]);
// Remove event handlers
client.AfterDisconnect -= AfterDisconnectHandler;
@@ -232,11 +233,11 @@ private static void AfterDisconnectHandler(object? sender, AfterDisconnectEventA
{
var client = (HiveMQClient)sender;
- if (client.LocalStore.ContainsKey("AfterDisconnectHandlerCalled"))
+ if (client.LocalStore.TryGetValue("AfterDisconnectHandlerCalled", out var value))
{
- var count = Convert.ToInt16(client.LocalStore["AfterDisconnectHandlerCalledCount"]);
+ var count = Convert.ToInt16(value, CultureInfo.InvariantCulture);
count++;
- client.LocalStore.Add("AfterDisconnectHandlerCalledCount", count.ToString());
+ client.LocalStore.Add("AfterDisconnectHandlerCalledCount", count.ToString(CultureInfo.InvariantCulture));
}
else
{
@@ -253,11 +254,11 @@ private static void OnDisconnectSentHandler(object? sender, OnDisconnectSentEven
{
var client = (HiveMQClient)sender;
- if (client.LocalStore.ContainsKey("OnDisconnectSentHandlerCalled"))
+ if (client.LocalStore.TryGetValue("OnDisconnectSentHandlerCalled", out var value))
{
- var count = Convert.ToInt16(client.LocalStore["OnDisconnectSentHandlerCalledCount"]);
+ var count = Convert.ToInt16(value, CultureInfo.InvariantCulture);
count++;
- client.LocalStore.Add("OnDisconnectSentHandlerCalledCount", count.ToString());
+ client.LocalStore.Add("OnDisconnectSentHandlerCalledCount", count.ToString(CultureInfo.InvariantCulture));
}
else
{