MQTT Client Library Encyclopedia – M2Mqtt

Guest post by Paolo Patierno

M2Mqtt
LanguageC#
Websitehttps://m2mqtt.wordpress.com
API-StyleAsynchronous
LicenseEclipse Public License

Description

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.

Features

MQTT 3.1
MQTT 3.1.1ok
LWTok
SSL/TLSok
Automatic Reconnectnok
Disk Persistencenok
QoS 0ok
QoS 1ok
QoS 2ok
Authenticationok
Throttlingnok
Offline Message Bufferingnok

Usage

Installation

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 !

Connect

In order to use the M2Mqtt library, first of all you need to create an instance of MqttClient class (in the uPLibrary.Networking.M2Mqtt namespace).

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.

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.

Remember to set the protocol version before calling the Connect() method.

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 Connect() method.

Publish

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 Publish() method.

Subscribe

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.

Unsubscribe

Unsubscribing from specific topics is very simple using the Unsubscribe() method provided by the MqttClient class.

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.

Disconnect

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 ConnectionClosed event.

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.

Author Information

Paolo Patierno
Senior Software Engineer and Microsoft MVP for Windows Embedded / Internet of Things who has been working on Microsoft technologies since 2006 with all .Net Frameworks (Micro, Compact and Desktop); he has been developing on embedded and mobile systems (based on Windows CE, WindowsPhone/Android and RTOS) since 2010, using C/C++, C# and Java. Focused on IoT and M2M communication. Member of DotNetCampania, TinyCLR.it and Embedded101 communities. Technical writer and owner of some open source projects on CodePlex and GitHub
   Website

30 comments

  1. Erthan Anderson says:

    Dear all

    how can i install MQTT Service on windows server (Broker server)

    Best reg.

  2. Hi Erthan,

    please take a look a the documentation (http://www.hivemq.com/docs/hivemq/latest). There is a chapter which explains how to install HiveMQ on Windows. There’s also a step-by-step guide to install HiveMQ as Windows service.

    Dominik from the HiveMQ Team

  3. haluk says:

    how can we get last value before publish?

  4. WisitP says:

    I got exception message when I tried to subscribe topic

    “An unhandled exception of type ‘uPLibrary.Networking.M2Mqtt.Exceptions.MqttClientException’ occurred in M2Mqtt.Net.dll”

    my env
    M2Mqtt.Net 4.3.0.0
    Mosquitto version 1.4.8
    MQTT v3.1

    below is my portion code
    MqttClient client = null;


    client = new MqttClient(this.MQTT_BROKER_ADDRESS);
    client.ProtocolVersion = MqttProtocolVersion.Version_3_1;
    clientId = Guid.NewGuid().ToString();
    client.MqttMsgPublishReceived += Client_MqttMsgPublishReceived;
    client.MqttMsgSubscribed += Client_MqttMsgSubscribed;

    private void subscribeButton_Click(object sender, EventArgs e)
    {
    try
    {
    string topic = topicSubTextBox.Text.Trim();
    client.Subscribe(new string[] { “/home/counter” }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE });
    }
    catch
    {
    Debug.WriteLine(“Something wrong”);
    }

    }

    please advice me.

    1. Hi,
      in the Subscribe method you are subscribing just to one topic “/home/counter” but the array with QoS has two elements. You have to specifiy an array with just one element to define the QoS level for your topic.

      Paolo.

    2. hal says:

      why dont you answer my question?

      to get latest message subscribed ( payload )

    3. Hi Hal,

      it’s not entirely clear to me what you are trying to achieve. Are you asking about retained messages? In this case I can recommend the following blog post: http://www.hivemq.com/blog/mqtt-essentials-part-8-retained-messages

      In case this was not your question, can you rephrase it? Thanks!

      All the best,
      Dominik from the HiveMQ Team

    4. WisitP says:

      Hi Paolo,
      It’s work for me. Thank you so much.

  5. WisitP says:

    Hi Paolo,
    It’s work for me, Thank you so much.

  6. Badarinath Katti says:

    Once I subscribe for the topic, the client should stay current to process the incoming published events.
    So, the client needs to be a service?
    The “MqttMsgPublishReceived ” is executed by MQTTClient thread?
    Please comment on the architecture of the client.

    Any direction is much appreciated.

    1. Patierno Paolo says:

      Publishing and receiving messages are executed in different threads.
      When you publish, the message is put inside an internal queue and there is a thread that check this queue to send messages outside.
      For all received messages there is another thread and the MqttMsgPublishReceived is executed inside it.

      Paolo

  7. Badarinath Katti says:

    Thanks for the comment. For these dedicated threads to function, main thread should be active right? So, the client should be something like a service?

  8. Jan Willem Teunisse says:

    Ciao, I installed today using Nuget the M2Mqtt dotnet library package on my windows10 development PC in order to publish a MQTT message using a Winbatch script. Winbatch support dotnet assemblies. The M2Mqtt package is installed in the Winbatch script directory using “nuget install M2Mqtt -o D:\Windows\Ontw”
    After installing the M2Mqtt package I saw 6 subdirectories in the d:\Windows\Ontw\M2Mqtt.4.3.0.0\lib\ directory. All containing different DLLs.
    I’m now confused which DLL I have to take to get the uPLibrary.Networking.M2Mqtt namespace and to define the object new MqttClient.

    So I need some suggestions or advice to proceed from here on.

    Beste regards,

    1. Hi Jan,

      I’m not sure of Paolo monitors this blog post regularly, however the author of this blog post is very active in the Paho Mailing list. You can find the mailing list here.

      Hope this helps,
      Dominik from the HiveMQ Team

  9. Jan Willem Teunisse says:

    Thanks for the comment, Dominik, I just register on the mailing list.

  10. santhosh says:

    HI all,
    I am new to .Net , can some one please post sample code creating MQTT client . I have root CA certificate and device certificate and device private key.
    help me in connecting to broker with the above certificates and publish to some topic.
    using TLS/ssl.

    1. Paul says:

      I have the same question. Did someone figure out how to do this?

  11. Eric Liao says:

    Hello Mr.Paolo:
    I have a question about how to use the the MQTT client class to receive retained messages when subscribe the topic.
    Thank you !!

    1. Clement says:

      Hi Eric, after subscribe to a topic, you can add Event handle of message receive which will contain the Topic and message received from subscribed topic try something like this:

      MqttClient nn = new MqttClient(“000.000.000.00”, 1883, false, null, null, 0, null, null);
      string[] sub = { “Main/#”};
      byte[] qos = { 1};
      nn.Subscribe(sub, qos);

      nn.MqttMsgPublishReceived += client_recievedMsg;

      public void client_recievedMsg(object sender, MqttMsgPublishEventArgs e)
      {
      byte[] msg = e.Message;
      string topic = e.Topic.ToString()
      }

      hope this will help you.

  12. Abhishek Swaraj says:

    Hi ,
    I am currently working in a Xamarin.Form project .and when i am trying to install nugets package for this client , i am getting following error ,
    “Could not install package ‘M2Mqtt 4.3.0’. You are trying to install this package into a project that targets ‘.NETPortable,Version=v4.5,Profile=Profile111’, but the package does not contain any assembly references or content files that are compatible with that frame”.
    Its looks like this M2MQTT client is not compatible with Xamarin.Form Project .net framework .
    Is there any way to use this M2MQTT client in Xamarin form project ?
    Any help will be appreciated .

  13. sHYAM says:

    Hi Paolo,

    I am integrating this m2mqtt library in my .net environment. I have some questions regarding this.

    1) Can we get persistence session using this M2MQTT?
    2) We have a scenario where message published by some interval with different topics. Can we get the topics consistently without disconnecting/re-subscribing?

  14. Ali says:

    Hi Paolo, I tried using m2mqtt library but getting the exception “The client and server do not possess a common algorithm”. Can you please help me out, here’s the StackOverflow link: http://stackoverflow.com/questions/40670451/m2mqtt-net-the-client-and-server-do-not-possess-a-common-algorithm

  15. Sonia says:

    When I compile my project I get the following error message (.net 4.5.1, C#):
    Reference type ‘IPAddress’ claims it is defined in ‘System’, but it could not be found.
    Anybody can help?

    1. Lukas says:

      I also have the same problem? Did you found any solution?

  16. anamika says:

    I tried to publish 3 messages and the event handler for publish shows
    Debug Trace:
    MessageId = 1 Published = True
    MessageId = 2 Published = True
    MessageId = 2 Published = True
    MessageId = 3 Published = True
    MessageId = 3 Published = True
    MessageId = 3 Published = True

    Why is it showing the published message so many times for the same messageID? Looks like it is showing 1 time for the first message, 2 times for the second and so on. I am using the AutoResetEvent class to wait and release to handle the asynchronous behavior.

    1. dfasdf says:

      do you set the event handler each time you publish a message? When you add an event handler twice, that means it will execute twice when the event occurs. It seems like you re-add the event handler every time you publish a message, leading it to execute twice when you publish 2 times, etc.

  17. Kerem says:

    Hi,

    I’m using Universal Windows Application for Windows Iot Core, and when I get your package from Nuget, it pulled the WinRt one, and it seems that it doesn’t support certificates which is also vital for AWS or other clouds. I couldn’t find any MqttClient constructor that takes certificate parameter.

    Could you please show me a way to pass a certificate to such clouds?

    Thanks

  18. Jovan says:

    I am using arduino and i want to control the lights to turn on and off when button is press.
    i believe that mqtt can make it work.
    For example if i press on, mqtt will probably send a value call 1 and if off is 0.
    So how do i actually make it to work when button press?,

  19. James says:

    Trying to disconnect and un-subscribe from topics causes issues.

    As far as un-subscribing – no errors are thrown, but nothing is happening by checking my broker I see that the topics are still subscribed by the client.

    Disconnect throws an “Object not set to an instance of an object”

    Included is my disconnect method code and the exception thrown during fail to disconnect.

    Method Code
    public void disconnectFromMQTT(List Topics)
    {
    foreach (string t in Topics)
    {
    myClient.Unsubscribe(new String[] { t } );
    myClient.MqttMsgUnsubscribed += client_MqttMsgUnsubscribed;
    }

    try
    {
    myClient.Disconnect();
    }
    catch(Exception e)
    {
    Console.WriteLine(Convert.ToString(e));
    }

    }

    Exception Thrown –
    Exception thrown: ‘uPLibrary.Networking.M2Mqtt.Exceptions.MqttCommunicationException’ in M2Mqtt.Net.dll
    uPLibrary.Networking.M2Mqtt.Exceptions.MqttCommunicationException —> System.NullReferenceException: Object reference not set to an instance of an object.
    at uPLibrary.Networking.M2Mqtt.MqttNetworkChannel.Send(Byte[] buffer) in c:\Users\ppatierno\Source\Repos\m2mqtt\M2Mqtt\Net\MqttNetworkChannel.cs:line 283
    at uPLibrary.Networking.M2Mqtt.MqttClient.Send(Byte[] msgBytes) in c:\Users\ppatierno\Source\Repos\m2mqtt\M2Mqtt\MqttClient.cs:line 1002
    — End of inner exception stack trace —
    at uPLibrary.Networking.M2Mqtt.MqttClient.Send(Byte[] msgBytes) in c:\Users\ppatierno\Source\Repos\m2mqtt\M2Mqtt\MqttClient.cs:line 1015
    at uPLibrary.Networking.M2Mqtt.MqttClient.Send(MqttMsgBase msg) in c:\Users\ppatierno\Source\Repos\m2mqtt\M2Mqtt\MqttClient.cs:line 1026
    at uPLibrary.Networking.M2Mqtt.MqttClient.Disconnect() in c:\Users\ppatierno\Source\Repos\m2mqtt\M2Mqtt\MqttClient.cs:line 610
    at MyHomeAuto.MQTT.disconnectFromMQTT(List`1 Topics) in G:\C#\Personal Programs\MyHomeAuto\MyHomeAuto\Classes\MQTT\MQTT.cs:line 63

  20. Raisa says:

    Hi!
    I tried to connect and I got exception message (Port is not standart. I use authentification)
    Exception of type ‘uPLibrary.Networking.M2Mqtt.Exceptions.MqttCommunicationException’ was thrown.

    My code:
    private void btn_mqtt_Connect_Click(object sender, EventArgs e){
    client = new MqttClient(IPAddress.Parse(ipAdress), port, false, null);
    client.Connect(Guid.NewGuid().ToString(), username, password);}

Leave a Reply

Your email address will not be published. Required fields are marked *