-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Support for [After|Before]Disconnect Events (#89)
- Loading branch information
1 parent
f36e7f8
commit fe7d12f
Showing
12 changed files
with
356 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
// Use IntelliSense to find out which attributes exist for C# debugging | ||
// Use hover for the description of the existing attributes | ||
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md | ||
"name": ".NET Core Launch (console)", | ||
"type": "coreclr", | ||
"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", | ||
"args": [], | ||
"cwd": "${workspaceFolder}", | ||
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console | ||
"console": "integratedTerminal", | ||
"stopAtEntry": false | ||
}, | ||
{ | ||
"name": ".NET Core Attach", | ||
"type": "coreclr", | ||
"request": "attach" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{ | ||
"version": "2.0.0", | ||
"tasks": [ | ||
{ | ||
"label": "build", | ||
"command": "dotnet", | ||
"type": "process", | ||
"args": [ | ||
"build", | ||
"${workspaceFolder}/Reconnect.csproj", | ||
"/property:GenerateFullPaths=true", | ||
"/consoleloggerparameters:NoSummary" | ||
], | ||
"problemMatcher": "$msCompile" | ||
}, | ||
{ | ||
"label": "publish", | ||
"command": "dotnet", | ||
"type": "process", | ||
"args": [ | ||
"publish", | ||
"${workspaceFolder}/Reconnect.csproj", | ||
"/property:GenerateFullPaths=true", | ||
"/consoleloggerparameters:NoSummary" | ||
], | ||
"problemMatcher": "$msCompile" | ||
}, | ||
{ | ||
"label": "watch", | ||
"command": "dotnet", | ||
"type": "process", | ||
"args": [ | ||
"watch", | ||
"run", | ||
"--project", | ||
"${workspaceFolder}/Reconnect.csproj" | ||
], | ||
"problemMatcher": "$msCompile" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
using HiveMQtt.Client; | ||
using HiveMQtt.Client.Options; | ||
using System.Text.Json; | ||
|
||
var topic = "hivemqtt/waiting/game"; | ||
|
||
var options = new HiveMQClientOptions(); | ||
options.Host = "127.0.0.1"; | ||
options.Port = 1883; | ||
|
||
var client = new HiveMQClient(options); | ||
|
||
// Add handlers | ||
// Message handler | ||
client.OnMessageReceived += (sender, args) => | ||
{ | ||
// Handle Message in args.PublishMessage | ||
Console.WriteLine($"--> Message Received: {args.PublishMessage.PayloadAsString}"); | ||
}; | ||
|
||
// This handler is called when the client is disconnected | ||
client.AfterDisconnect += async (sender, args) => | ||
{ | ||
var client = (HiveMQClient)sender; | ||
|
||
Console.WriteLine($"AfterDisconnect Handler called with args.CleanDisconnect={args.CleanDisconnect}."); | ||
|
||
// We've been disconnected | ||
if (args.CleanDisconnect) | ||
{ | ||
Console.WriteLine("--> AfterDisconnectEventArgs indicate a clean disconnect."); | ||
Console.WriteLine("--> A clean disconnect was requested by either the client or the broker."); | ||
} | ||
else | ||
{ | ||
Console.WriteLine("--> AfterDisconnectEventArgs indicate an unexpected disconnect."); | ||
Console.WriteLine("--> This could be due to a network outage, broker outage, or other issue."); | ||
Console.WriteLine("--> In this case we will attempt to reconnect periodically."); | ||
|
||
// We could have been disconnected for any number of reasons: network outage, broker outage, etc. | ||
// Here we loop with a backing off delay until we reconnect | ||
|
||
// Start with a small delay and double it on each retry up to a maximum value | ||
var delay = 5000; | ||
var reconnectAttempts = 0; | ||
|
||
while (true) | ||
{ | ||
await Task.Delay(delay).ConfigureAwait(false); | ||
reconnectAttempts++; | ||
|
||
if (reconnectAttempts > 3) | ||
{ | ||
Console.WriteLine("--> Maximum reconnect attempts exceeded. Exiting."); | ||
break; | ||
} | ||
|
||
try | ||
{ | ||
Console.WriteLine($"--> Attempting to reconnect to broker. This is attempt #{reconnectAttempts}."); | ||
var connectResult = await client.ConnectAsync().ConfigureAwait(false); | ||
|
||
if (connectResult.ReasonCode != HiveMQtt.MQTT5.ReasonCodes.ConnAckReasonCode.Success) | ||
{ | ||
Console.WriteLine($"--> Failed to connect: {connectResult.ReasonString}"); | ||
|
||
// Double the delay with each failed retry to a maximum | ||
delay = Math.Min(delay * 2, 30000); | ||
Console.WriteLine($"--> Will delay for {delay / 1000} seconds until next try."); | ||
} | ||
else | ||
{ | ||
Console.WriteLine("--> Reconnected successfully."); | ||
break; | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
Console.WriteLine($"--> Failed to connect: {ex.Message}"); | ||
|
||
// Double the delay with each failed retry to a maximum | ||
delay = Math.Min(delay * 2, 10000); | ||
Console.WriteLine($"--> Will delay for {delay / 1000} seconds until next try."); | ||
} | ||
} | ||
} // if (args.CleanDisconnect) | ||
|
||
Console.WriteLine("--> Exiting AfterDisconnect handler."); | ||
}; | ||
|
||
// Attempt to connect to the broker | ||
try | ||
{ | ||
var connectResult = await client.ConnectAsync().ConfigureAwait(false); | ||
if (connectResult.ReasonCode != HiveMQtt.MQTT5.ReasonCodes.ConnAckReasonCode.Success) | ||
{ | ||
throw new Exception($"Failed to connect to broker: {connectResult.ReasonString}"); | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
Console.WriteLine($"Failed to connect to broker: {ex.Message}"); | ||
return; | ||
} | ||
|
||
// Subscribe to a topic | ||
Console.WriteLine($"Subscribing to {topic}..."); | ||
await client.SubscribeAsync(topic).ConfigureAwait(false); | ||
|
||
Console.WriteLine($"We are connected to the broker and will be waiting indefinitely for messages or a disconnect."); | ||
Console.WriteLine($"--> Publish messages to {topic} and they will be printed."); | ||
Console.WriteLine($"--> Shutdown/disconnect the broker and see the AfterDisconnect code execute."); | ||
|
||
await Task.Delay(1000).ConfigureAwait(false); | ||
|
||
// Publish a message | ||
Console.WriteLine("Publishing a test message..."); | ||
var resultPublish = await client.PublishAsync( | ||
topic, | ||
JsonSerializer.Serialize(new | ||
{ | ||
Command = "Hello", | ||
}) | ||
).ConfigureAwait(false); | ||
|
||
|
||
while (true) | ||
{ | ||
await Task.Delay(2000).ConfigureAwait(false); | ||
Console.WriteLine("Press q exit..."); | ||
if (Console.ReadKey().Key == ConsoleKey.Q) | ||
{ | ||
Console.WriteLine("\n"); | ||
break; | ||
} | ||
} | ||
|
||
Console.WriteLine("Disconnecting gracefully..."); | ||
await client.DisconnectAsync().ConfigureAwait(false); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net7.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<!-- Use the HiveMQtt project as a local source. Otherwise, fetch from nuget. --> | ||
<PropertyGroup> | ||
<RestoreSources>$(RestoreSources);../../Source/HiveMQtt/bin/Debug/;https://api.nuget.org/v3/index.json</RestoreSources> | ||
</PropertyGroup> | ||
|
||
<!-- Update the version to match --> | ||
<ItemGroup> | ||
<PackageReference Include="HiveMQtt" Version="0.4.0" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.