Messaging with MQTT and .NET
In the time of IoT and Cloud, MQTT is no question a very popular protocol in community. However, Azure Messaging services, designed and operated by Microsoft as PaaS, provides a layer of abstraction on top of the underlying protocol. For example, Service Bus, which is core of messaging, is using HTTP/REST, AMQP and SBNP (originally first SB protocol. Today deprecting) protocols. But typically, developers do not deal with protocols, because Microsoft always (not only in context of messaging) provides simplification SDK. You might say, “but HTTP/REST is simple enough”. This is not true, when it comes to productivity.
But, when working IoT, MQTT is supported as IoTHub endpoint. In some scenarios, customers want to run messaging locally (On-Prem only) and IotHub cannot be used.
Especially, developers from none Microsoft community tend to use native protocols for messaging. If you as .NET developer fall into this strategy, you will probably feel slowed-down in productivity. But, mostly in such cases, you will not have to support the full power of Microsoft messaging.
In this article I will show some examples, which describe following:
- How to run MQTT server locally?
- How to send/receive messages by using of .NET ?
- How to send receive messages by using of .NET Core?
How to run MQTT server locally?
To run the MQTT server locally I have decided to use Eclipse Mosquitto, which can be pulled from here.
It is a docker image, which provide a MQTT server functionality.
docker run -it -p 1883:1883 -p 9001:9001 eclipse-mosquitto
Once it is started, you will see following:
>docker run -it -p 1883:1883 -p 9001:9001 eclipse-mosquitto
mosquitto[1]: mosquitto version 1.4.12 (build date 2017-06-01 13:03:46+0000) starting
mosquitto[1]: Config loaded from /mosquitto/config/mosquitto.conf.
mosquitto[1]: Opening ipv4 listen socket on port 1883.
mosquitto[1]: Opening ipv6 listen socket on port 1883.
Your local MQTT server is ready now.
How to send/receive messages by using of .NET
To start with MQTT in .NET I have found this application. It is using mqttlib.dll.
Following code shows how to create a subscription and how to publish a message to topic.
// Connects to your locally running MQTT server in docker container.
string connectionString = "tcp://localhost:1883";
client = MqttClientFactory.CreateClient(connectionString, clientId);
client.Connect(true);
client.Connected += new ConnectionDelegate(client_Connected);
client.ConnectionLost += new ConnectionDelegate(_client_ConnectionLost);
client.PublishArrived += new PublishArrivedDelegate(client_PublishArrived);
client.Published += new CompleteDelegate(_client_Published);
...
// Subscribe listener at topic
client.Subscribe("eebus/daenet/telemetry", QoS.BestEfforts);
...
// Publish a message to topic
client.Publish(topic, payload, QoS.BestEfforts, false);
How to send receive messages by using of .NET Core?
To implement MQTT functionality I have used a XAMARIN package System.Net.Mqtt
Here is the package reference copied from project file:
<PackageReference Include="System.Net.Mqtt" Version="0.5.42-beta" />
Following is the full source code, which shows how to subscribe messages from topic and hot to publish messages to topic.
using System;
using System.Net.Mqtt;
using System.Threading.Tasks;
using System.Linq;
using Newtonsoft.Json;
using System.Text;
namespace daenet.iot
{
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine("Hello, World!");
var mqttClient = MqttClient.CreateAsync("localhost").Result ;
var sess = mqttClient.ConnectAsync().Result;
string rcvTopic = "eebus/daenet/command";
string sendTopic = "eebus/daenet/telemetry";
mqttClient.SubscribeAsync(rcvTopic, MqttQualityOfService.ExactlyOnce);
Task.Run(() =>
{
while (true)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Enter the text to send.");
Console.ForegroundColor = ConsoleColor.Cyan;
var line = System.Console.ReadLine();
var data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(line));
mqttClient.PublishAsync(new MqttApplicationMessage(sendTopic, data), MqttQualityOfService.ExactlyOnce).Wait();
}
});
mqttClient.MessageStream.Subscribe(msg =>
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(Encoding.UTF8.GetString(msg.Payload));
Console.ResetColor();
});
}
}
}
Recap
By using of these two applications and local MQTT server in docker container you can send and receive messages. Following short video shows both applications in action.