I have a very simple C# command line app that connects to an MQTT server and prints messages to the console.
using MQTTnet;
using MQTTnet.Client.Options;
using MQTTnet.Extensions.ManagedClient;
using System.Text;
var options = new MqttClientOptionsBuilder()
.WithTcpServer(MqttConfig.Server, MqttConfig.Port)
.WithCredentials(MqttConfig.User, MqttConfig.Password)
.WithClientId("MqttTest")
.WithCleanSession()
.Build();
var MqttClient = new MqttFactory().CreateMqttClient();
var cancellationToken = new CancellationToken();
var subscribeOptions = new MQTTnet.Client.Subscribing.MqttClientSubscribeOptions();
subscribeOptions.TopicFilters.Add(new MqttTopicFilter { Topic = MqttConfig.Topic });
MqttClient.ConnectAsync(options, cancellationToken);
MqttClient.SubscribeAsync(subscribeOptions, cancellationToken);
MqttClient.UseApplicationMessageReceivedHandler(e => { HandleMessageReceived(e.ApplicationMessage); });
while (true)
{
Task.Delay(1000).GetAwaiter().GetResult();
}
static void HandleMessageReceived(MqttApplicationMessage applicationMessage)
{
Console.WriteLine("### RECEIVED MESSAGE ###");
Console.WriteLine($"+ Topic = {applicationMessage.Topic}");
Console.WriteLine($"+ Payload = {Encoding.UTF8.GetString(applicationMessage.Payload)}");
Console.WriteLine();
}
abstract class MqttConfig
{
public static readonly string Server = "servername";
public static readonly int Port = 1883;
public static readonly string User = "user";
public static readonly string Password = "password";
public static readonly string Topic = "#";
}
Putting the MqttConfig
class information into an app like MQTT X shows a bunch of incoming messages. But running this C# app just shows a blank console.
I ended up basing the application on an MQTTnet sample. I'm posting it as an answer here in case anyone else has the same question in the future.
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;
using System.Text.Json;
#region Subscribe to topic & handle incoming messages
var mqttFactory = new MqttFactory();
using (var mqttClient = mqttFactory.CreateMqttClient())
{
var mqttClientOptions = new MqttClientOptionsBuilder()
.WithTcpServer(MqttConfig.Server, MqttConfig.Port)
.WithCredentials(MqttConfig.User, MqttConfig.Password)
.Build();
mqttClient.UseApplicationMessageReceivedHandler(e =>
{
Console.WriteLine("Received application message.");
e.DumpToConsole();
return Task.CompletedTask;
});
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
.WithTopicFilter(f => f.WithTopic(MqttConfig.Topic))
.Build();
await mqttClient.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);
Console.WriteLine("MQTT client subscribed to topic.");
Console.ReadLine(); // Prevents app from immediately closing once MQTT subscription is complete.
// Will close if user presses "enter" before any messages are received.
}
static class ObjectExtensions
{
public static TObject DumpToConsole<TObject>(this TObject @object)
{
var output = "NULL";
if (@object != null)
{
output = JsonSerializer.Serialize(@object, new JsonSerializerOptions { WriteIndented = true });
}
Console.WriteLine($"[{@object?.GetType().Name}]:\r\n{output}");
return @object;
}
}
#endregion
static class MqttConfig
{
public static readonly string Server = "servername";
public static readonly int Port = 1883;
public static readonly string User = "user";
public static readonly string Password = "password";
public static readonly string Topic = "#";
}