I'm having trouble getting some basic C# code running with MQTTnet 4.1 examples.
Using this test code at https://blog.behroozbc.ir/mqtt-client-with-mqttnet-4-and-c , and also referencing the samples at https://github.com/dotnet/MQTTnet/blob/9cbd5dd778dec7308c079dd61652d9ab573bf186/Samples/Client/Client_Subscribe_Samples.cs ,
I am struggling to make a clean connection to the broker, and thereby publish/subscribe to a topic.
I'm working with VS2019, and installed NuGet package MQTTnet.4.1.4.563
Here's my Program.cs with a ConnectAndSendMessage method. My test EMQX Broker (the desktop client is called MQTTX) is running on my local box - and my Angular web client sends/receives message without issue.
using System;
using System.Threading.Tasks;
using System.Threading;
using MQTTnet.Client;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet;
using System.Text.Json;
namespace mqtt_dotnet_sample1
{
class Program
{
static void Main(string[] args)
{
Task task = ConnectAndSendMessage();
}
public static async Task ConnectAndSendMessage()
{
IManagedMqttClient _mqttClient = new MqttFactory().CreateManagedMqttClient();
MqttClientOptionsBuilder builder = new MqttClientOptionsBuilder()
.WithClientId("MY_CLIENT_ID") // here is the same conn str as my TypeScript client in Angular 14
.WithWebSocketServer("broker.emqx.io");
ManagedMqttClientOptions options = new ManagedMqttClientOptionsBuilder()
.WithAutoReconnectDelay(TimeSpan.FromSeconds(60))
.WithClientOptions(builder.Build())
.Build();
// Set up handlers
_mqttClient.ConnectedAsync += _mqttClient_ConnectedAsync;
_mqttClient.DisconnectedAsync += _mqttClient_DisconnectedAsync;
_mqttClient.ConnectingFailedAsync += _mqttClient_ConnectingFailedAsync;
// Connect to the broker
Console.WriteLine("Attempting to connect to broker...");
await _mqttClient.StartAsync(options);
// Send a new message to the broker every second
while (true)
{
string json = JsonSerializer.Serialize(new { message = "Hi from MqttNet", sent = DateTime.UtcNow });
await _mqttClient.EnqueueAsync("bob-top", json);
await Task.Delay(TimeSpan.FromSeconds(10)); // ** IT BAILS OUT HERE **
}
Task _mqttClient_ConnectedAsync(MqttClientConnectedEventArgs arg)
{
Console.WriteLine("Connected");
return Task.CompletedTask;
};
Task _mqttClient_DisconnectedAsync(MqttClientDisconnectedEventArgs arg)
{
Console.WriteLine("Disconnected");
return Task.CompletedTask;
};
Task _mqttClient_ConnectingFailedAsync(ConnectingFailedEventArgs arg)
{
Console.WriteLine("Connection failed check network or broker!");
return Task.CompletedTask;
}
}
}
}
It just exists at this line: await Task.Delay(TimeSpan.FromSeconds(10));
and shows the following messages in the VS Output window - the final message being The program '[787944] mqtt-dotnet-sample1.exe' has exited with code 0 (0x0).
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll'.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\mqtt-dotnet-sample1.exe'. Symbols loaded.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\MQTTnet.dll'.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\MQTTnet.Extensions.ManagedClient.dll'.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\System.Text.Json.dll'.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\netstandard\v4.0_2.0.0.0__cc7b13ffcd2ddd51\netstandard.dll'.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll'.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll'.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\Microsoft.Bcl.AsyncInterfaces.dll'.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll'.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\System.Memory.dll'.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll'.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\System.ValueTuple.dll'.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\System.Text.Encodings.Web.dll'.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\System.Runtime.CompilerServices.Unsafe.dll'.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\System.Threading.Tasks.Extensions.dll'.
'mqtt-dotnet-sample1.exe' (CLR v4.0.30319: mqtt-dotnet-sample1.exe): Loaded 'c:\bob\dev\mqtt-dotnet-sample1\mqtt-dotnet-sample1\bin\Debug\System.Buffers.dll'.
The program '[787944] mqtt-dotnet-sample1.exe' has exited with code 0 (0x0).
Any advice or help is appreciated.
Your MQTT Code looks fine (at least on first glance). The problem is, that ConnectAndSendMessage
returns a Task
. This has to be await
ed in the main method. Otherwise, the Task is created, assigned to the variable task
and then the end of the main method is reached -> the program exits.
To await the Task, you can change your main method one of the following ways:
async static void Main(string[] args)
{
await ConnectAndSendMessage();
}
static void Main(string[] args)
{
Task task = ConnectAndSendMessage();
task.GetAwaiter().GetResult();
}