Skip to content

Commit

Permalink
New & Updated Example Applications, Tools and Utilities (#103)
Browse files Browse the repository at this point in the history
  • Loading branch information
pglombardo authored Oct 30, 2023
1 parent 4a0312d commit 9d70806
Show file tree
Hide file tree
Showing 12 changed files with 353 additions and 1 deletion.
26 changes: 26 additions & 0 deletions Examples/ConnectReceiveAndPublish/.vscode/launch.json
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/net6.0/ConnectReceiveAndPublish.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"
}
]
}
41 changes: 41 additions & 0 deletions Examples/ConnectReceiveAndPublish/.vscode/tasks.json
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}/ConnectReceiveAndPublish.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/ConnectReceiveAndPublish.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/ConnectReceiveAndPublish.csproj"
],
"problemMatcher": "$msCompile"
}
]
}
18 changes: 18 additions & 0 deletions Examples/ConnectReceiveAndPublish/ConnectReceiveAndPublish.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<PropertyGroup>
<RestoreSources>$(RestoreSources);../../Source/HiveMQtt/bin/Debug/;https://api.nuget.org/v3/index.json</RestoreSources>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="HiveMQtt" Version="0.5.0" />
</ItemGroup>

</Project>
88 changes: 88 additions & 0 deletions Examples/ConnectReceiveAndPublish/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System.Text;
using System.Text.Json;
using HiveMQtt.Client;
using HiveMQtt.Client.Options;
using HiveMQtt.MQTT5.Types;

var options = new HiveMQClientOptions
{
Host = "127.0.0.1",
Port = 1883,
CleanStart = false, // <--- Set to false to receive messages queued on the broker
ClientId = "ConnectReceiveAndPublish",
};

var client = new HiveMQClient(options);

// Message Handler
//
// It's important that this is setup before we connect to the broker
// otherwise queued messages that are sent down may be lost.
//
client.OnMessageReceived += (sender, args) =>
{
var jsonString = args.PublishMessage.PayloadAsString;
var jsonDocument = JsonDocument.Parse(jsonString);

// Traverse the JSON document using the JsonElement API
var root = jsonDocument.RootElement;
var message_number = root.GetProperty("MessageNumber").GetInt32();

Console.WriteLine($"Message Received; topic={args.PublishMessage.Topic}, message number={message_number}");
};

// Connect to the broker
var connectResult = await client.ConnectAsync().ConfigureAwait(false);
if (connectResult.ReasonCode != HiveMQtt.MQTT5.ReasonCodes.ConnAckReasonCode.Success)
{
throw new Exception($"Failed to connect: {connectResult.ReasonString}");
}

// Subscribe to a topic
var topic = "hivemqtt/sendmessageonloop";
var subscribeResult = await client.SubscribeAsync(topic, QualityOfService.ExactlyOnceDelivery).ConfigureAwait(false);
Console.WriteLine($"Subscribed to {topic}: {subscribeResult.Subscriptions[0].SubscribeReasonCode}");

Console.WriteLine("Waiting for 10 seconds to receive messages queued on the topic...");
await Task.Delay(10000).ConfigureAwait(false);

Console.WriteLine(string.Empty);
Console.WriteLine("Now publishing a QoS2 message every 15 seconds. Press Q to quit.");

// Publish Loop - press q to exit
var message_number = 0;
while (true)
{
message_number++;
var payload = JsonSerializer.Serialize(new
{
Content = "ConnectReceiveAndPublish",
MessageNumber = message_number,
});

var message = new MQTT5PublishMessage
{
Topic = topic,
Payload = Encoding.ASCII.GetBytes(payload),
QoS = QualityOfService.ExactlyOnceDelivery,
};

var resultPublish = await client.PublishAsync(message).ConfigureAwait(false);
Console.WriteLine($"Published QoS2 message {message_number} to topic {topic}: {resultPublish.QoS2ReasonCode}");

for (var x = 0; x < 5; x++)
{
await Task.Delay(3750).ConfigureAwait(false);

if (Console.KeyAvailable)
{
if (Console.ReadKey().Key == ConsoleKey.Q)
{
Console.WriteLine("Disconnecting gracefully...");
await client.DisconnectAsync().ConfigureAwait(false);
return;
}
}
}
}

12 changes: 12 additions & 0 deletions Examples/ConnectReceiveAndPublish/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# ConnectReceiveAndPublish

This example illustrates connecting to a broker with `CleanStart=false`. In this case, upon connecting,
the broker will immediately send down any queued messages. This can be a large amount in some cases.

For this reason, it's critical that the `OnMessageReceived` handler is configured before connecting to the broker.

This example will connect to the broker with `CleanStart=false`, wait 10 seconds for any queued messages and
then begin to publish Quality of Service Level 2 messages periodically.

This example can be using in conjunction with `SendMessageOnLoop` to test `CleanStart` and handling queued
messages.
5 changes: 5 additions & 0 deletions Examples/Reconnect/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Reconnect

This example illustrates how to implement a re-connect hander on the `AfterDisconnect` event.

See the source code in `Program.cs` for details.
2 changes: 1 addition & 1 deletion Examples/Reconnect/Reconnect.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HiveMQtt" Version="0.4.3" />
<PackageReference Include="HiveMQtt" Version="0.5.0" />
</ItemGroup>

<ItemGroup>
Expand Down
26 changes: 26 additions & 0 deletions Examples/SendMessageOnLoop/.vscode/launch.json
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/net6.0/SendMessageOnLoop.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"
}
]
}
41 changes: 41 additions & 0 deletions Examples/SendMessageOnLoop/.vscode/tasks.json
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}/SendMessageOnLoop.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/SendMessageOnLoop.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/SendMessageOnLoop.csproj"
],
"problemMatcher": "$msCompile"
}
]
}
71 changes: 71 additions & 0 deletions Examples/SendMessageOnLoop/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System.Text;
using System.Text.Json;
using HiveMQtt.Client;
using HiveMQtt.Client.Options;
using HiveMQtt.MQTT5.Types;

// Connect to localhost:1883. Change for brokers elsewhere.
// Run HiveMQ CE locally: docker run --name hivemq-ce -d -p 1883:1883 hivemq/hivemq-ce
//
var options = new HiveMQClientOptions
{
Host = "127.0.0.1",
Port = 1883,
CleanStart = false,
ClientId = "SendMessageOnLoop",
};

var client = new HiveMQClient(options);

// Connect to the broker
var connectResult = await client.ConnectAsync().ConfigureAwait(false);
if (connectResult.ReasonCode != HiveMQtt.MQTT5.ReasonCodes.ConnAckReasonCode.Success)
{
throw new Exception($"Failed to connect: {connectResult.ReasonString}");
}

// Example Settings
var wait = 50; // The delay between each message
Console.WriteLine($"Starting {wait / 1000} second loop... (press q to exit)");

// Topic to send messages to
var topic = "hivemqtt/sendmessageonloop";

// Counter for messages sent
var message_number = 0;

// Main loop - press q to exit
// Send QoS 2 messages to the broker
//
while (true)
{
message_number++;
var payload = JsonSerializer.Serialize(new
{
Content = "SendMessageOnLoop",
MessageNumber = message_number,
});

var message = new MQTT5PublishMessage
{
Topic = topic,
Payload = Encoding.ASCII.GetBytes(payload),
QoS = QualityOfService.ExactlyOnceDelivery,
};

var resultPublish = await client.PublishAsync(message).ConfigureAwait(false);
Console.WriteLine($"Published message {message_number} to topic {topic}: {resultPublish.QoS2ReasonCode}");

await Task.Delay(wait).ConfigureAwait(false);

if (Console.KeyAvailable)
{
if (Console.ReadKey().Key == ConsoleKey.Q)
{
break;
}
}
}

Console.WriteLine("Disconnecting gracefully...");
await client.DisconnectAsync().ConfigureAwait(false);
6 changes: 6 additions & 0 deletions Examples/SendMessageOnLoop/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SendMessageOnLoop

This simple example program simply connects to the local broker and repeatedly sends Quality of Service
level 2 messages to the broker.

See the source code in `Program.cs` for details and options to configure the behavior.
18 changes: 18 additions & 0 deletions Examples/SendMessageOnLoop/SendMessageOnLoop.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<PropertyGroup>
<RestoreSources>$(RestoreSources);../../Source/HiveMQtt/bin/Debug/;https://api.nuget.org/v3/index.json</RestoreSources>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="HiveMQtt" Version="0.5.0" />
</ItemGroup>

</Project>

0 comments on commit 9d70806

Please sign in to comment.