MQTT Client Library Encyclopedia – M2Mqtt
Written by Paolo Patierno
Category: MQTT MQTT Client Library
Published: July 25, 2015
|License||Eclipse Public License|
Until October 2014, the Eclipse Paho (the umbrella project for all the main MQTT clients) didn’t have an implementation based on Microsoft technologies. It had support for a lot of different programming languages, but not for C#. For this reason, the Eclipse Foundation asked me to take my M2Mqtt library under Paho umbrella, to make its offer more complete. In this way, M2Mqtt project (who was born in the April 2013) became the official C# implementation of Eclipse Paho, and provided an MQTT client for all .Net Framework platforms (full, compact and micro) and WinRT (Windows 8.1, Windows Phone 8.1 and the future Windows 10).
Today the library is more mature and production ready. There are lots of makers using it in their hobbystic projects, and more companies are deploying it in their Internet of Things solutions up and running 24⁄7. M2Mqtt provides all the main features of the MQTT standard from all the three QoS levels and “last will and testament” to SSL/TLS support. It exposes an API that works in an asynchronous fashion even if not in the “Task based” way that the new async/await keywords (C# 5.0) need. Of course this could be a future improvement, because the project is always under development and the team (me and myself) accept all types of suggestions or contributes to it.
|Offline Message Buffering|
The M2Mqtt library is available in two different ways:
- as source code on the official Eclipse Paho project or Github that you have to build
- as a “cooked” Nuget package that you can simply reference from your Visual Studio project using the built-in Nuget Package Manager or the related console. (preferred way for all .Net developers)
It has no dependencies and the referenced assembly changes due to the type of project you are working on (.Net Framework, .Net Micro Framework, Windows 8.1 and so on) : Nuget manager takes care of those issues for you !
In order to use the M2Mqtt library, first of all you need to create an instance of MqttClient class (in the
MqttClient client = new MqttClient("broker.hivemq.com");
The simplest overload of the MqttClient class constructor needs only the MQTT broker URL as parameter without specifying the protocol (it’s TCP) and the port (the default is 1883); it can be an host name or an IP address. There are other overloads that you can use to specify:
- A different port (not standard 1883 or 8883 for TLS/SSL connection)
- The X509 certificate needed for a TLS/SSL connection to the broker (as we’ll see in the following sections)
- Optional callbacks for above certificate validation
After creating an MqttClient object you need to call the Connect( ) method to connect to the broker.
byte code = client.Connect(Guid.NewGuid().ToString());
The simplest overload of this method needs only the client id that in the above example is generated as a GUID. It’s important to say that the library uses MQTT 3.1.1 specification as default so it hasn’t the 23 characters limit for the client id as in the previous MQTT 3.1 specification. The Connect( ) method is synchronous and it returns a byte that represents the response code from the broker; from the MQTT specification it’s value is 0 if the connection was accepted or a number greater than 0 identifying the reason of connection failure. During the client life you can always retrieve the client id and the connection status accessing to the ClientId and IsConnected properties. All the other overloads of the connection method allow you to specify :
- Username and password for authentication (they are null as default, no authentication)
- “Clean session” flag that you can set to false so that the broker will save the client session on disconnection (subscribed topics, messages for these topics delivered on reconnection). Please note that the default value is true, so the broker doesn’t save any session information about the client
- “Keep alive period” used by the client to send the ping message as “heart beat” (the default value is 60 seconds)
- All information related to the “last will and testament” feature like the will topic, will message, will Qos level and will retain flag (of course, they are null as default)
Connect with MQTT 3.1 or MQTT 3.1.1
By default, M2Mqtt connects to the broker using the new MQTT 3.1.1 specification but if you have an old MQTT 3.1 compliant broker you can set this version using the
ProtocolVersion property of the
MqttClient instance in the following way.
client.ProtocolVersion = MqttProtocolVersion.Version_3_1;
Remember to set the protocol version before calling the
Connect with LWT
As mentioned before, in order to use the “last will and testament” feature you can specify all the needed parameters to the more complete
Connect() method overload.
Connect with Username / Password
The authentication feature using username and password is enabled by specifying these parameters in the
byte code = client.Connect(Guid.NewGuid().ToString(), "username", "password");
As you know, the MQTT protocol supports the publish/subscribe pattern so the main operation you can do with a client for sending messages to other clients is the publish action. The
MqttClient class provides the
Publish() method to publish a message (with related body) to a specific topic with a defined QoS level. Before you call the above method, you can register an event handler for the
MqttMsgPublished event provided by the
MqttClient instance to know when the message was (or wasn’t) published to the broker.
As you can see, you can specify the destination topic, the message body (as an array of bytes), the QoS level for publishing to the broker and the retain flag. This call returns immediately the id assigned to the message that will be sent shortly after. The library works in an asynchronous way with an internal queue and an internal thread for publishing messages.
The event related to the publish method is raised when the message is published to the broker or when an error is detected. An error means that the client made more attempts to send the message but it couldn’t reach the broker (of course this is true only for QoS level 1 and 2 where an acknowledge sequence from broker is expected). You can check if the message was published or not, using the
IsPublished property of the received event args (you receive the MessageId too).
Publish a retained Message
You can publish a retained message simply by setting to true the retain flag parameter in the above
In order to receive messages published on one or more topics from other clients, you need to use Subscribe( ).
It receives two arrays as input parameters : the former is the list of topics you want to subscribe and the latter is the related list of QoS levels (one for each topic). As for publishing, the
MqttClient class provides the
MqttMsgSubscribed event that is raised when the client is correctly subscribed to the topic (receiving acknowledge from broker).
Also in this case, the
Subscribe() method returns the id of the subscribe message sent to the broker. You can use it to correlate the information you’ll receive in the event args of the above subscribed event.
After subscribing to a topic, you start to receive messages published on this topic. To be notified about received messages, there is the
MqttMsgPublishReceived event you can register to.
The related event args provides you all information about the message received like topic, QoS level, message body (as array of bytes) and the retain flag.
Unsubscribing from specific topics is very simple using the
Unsubscribe() method provided by the
You have to provide the list of topics you want to unsubscribe from. As for the publishing, the
MqttClient class provides the
MqttMsgUnsubscribed event that is raised when the client receives the confirmation from the broker that the unsubscribe request was successful. As for subscribing, in this case you can use the message id, returned by
Unsubscribe() method, for correlating the information received in the event args.
The disconnection from the broker is possible using the
Disconnect() method that is synchronous and returns when all internal threads ends gracefully.
A client can disconnect gracefully using the above method but the connection could be lost due to network problems or closed broker. In this case, you can register to the
client.ConnectionClosed += client_ConnectionClosed;
Using TLS / SSL
M2Mqtt supports secure connection to an MQTT broker using the SSL/TLS protocol and X509 certificates. First of all you need to get the CA certificate used to sign the broker certificate you’ll connect to. For more information about certificate creation you can read the following article on my Embedded101 community blog (there is an example using OpenSSL). After that, you need to provide the certificate as resource inside your .Net project using a resources file (
Resources.resx) that exposes the certificate itself as a byte stream.
As you can see, one of the overloads of the
MqttClient class constructor has an instance of
X509Certificate class as input parameter that we can use to provide our CA certificate from resources file.
To have a more fine grained control on certificate validation you can provide another parameter as
RemoteCertificateValidationCallback. This is a callback routine that the .Net runtime calls for you when it needs to validate a server certificate.
The above callback provides you all information and data you need to validate the server certificate based on your client application policy.