Paho MQTT C Client - MQTT Client Library Encyclopedia
The Paho C client libraries started life back in 2007, when I first started writing a small MQTT server, RSMB (Really Small Message Broker). I thought I would reuse as much of the internal code of RSMB as I could, to save myself some time. As it turned out, I probably didn’t save as much time as I expected, because in some ways writing a client library for MQTT is more complex than writing a server. RSMB is single-threaded, which I mainly retained in the design of these client libraries, for better or worse.
I started writing RSMB in C++, but the template support in gcc at the time did not work well, so I switched to standard ANSI C. That’s why the client libraries are C too. It seemed to me at the time that Linux was likely to take over the world for embedded systems, with Windows CE maybe getting a look in. That’s why I wrote these libraries with Linux (and some other forms of Unix) and Windows in mind, rather than being any more portable. And that’s why the Paho embedded client libraries now exist - for all those other embedded operating systems that are now popular!
In 2008, there weren’t too many MQTT client libraries to learn from, so for the first steps I followed the IBM Java client of the time. I thought it was better to copy an existing model to make it easier for the MQTT application programmer to transfer knowledge from one to the other. As a result the synchronous client was born, just called MQTTClient. This has the following design points:
threading: no background thread, or just one, regardless of how many connections are created
blocking MQTT calls, to simplify application programming
an inflight window for QoS 1 and 2 messages of 1 or 10 only, to limit the amount of damage that can be inflicted on a server
internal tracing and memory tracking, for serviceability and elimination of memory leaks
Overview of Paho MQTT C Client
Paho MQTT C Client | |
---|---|
Language | C |
License | EPL and EDL |
Website | eclipse.org/paho/clients/c |
API Style | Blocking and non-blocking |
Features Supported by Paho MQTT C Client
Feature | |
---|---|
MQTT 3.1 | Yes |
MQTT 3.1.1 | Yes |
LWT | Yes |
SSL/TLS | Yes |
Automatic Reconnect | No |
Disk Persistence | Yes |
Advance Features: Paho MQTT C Client
Feature | |
---|---|
QoS 0 | Yes |
QoS 1 | Yes |
QoS 2 | Yes |
Authentication | Yes |
Throttling | No |
Offline Message Buffering | No |
How to Use Paho MQTT C Client?
Installation of Paho MQTT C Client
On Linux (or Unix) the simplest method is to clone the repo and install:
Pre-built libraries for MacOS and Windows are available on the Paho downloads page.
Unzip to a location of your choice.
First, we have to include the header file.
Now, we can create a client object.
Where the url is of the form host:port
, and clientid
is a string
. The fourth parameter specifies the disk persistence required. MQTTCLIENT_PERSISTENCE_NONE
says that no persistence is required. MQTTCLIENT_PERSISTENCE_DEFAULT
asks for the supplied, default disk persistence to be used. This stores all inflight message data to disk, and means that the application can end, restart, and recreate the client object with the same clientid and url. Any inflight message data will be read from disk and restored so that the application can continue where its previous incarnation left off.
Next, we can optionally set some callback functions. At a minimum, we must have a messageArrived callback
, which will be called whenever an MQTT publish message arrives.
There is also a connectionLost callback
which will be called whenever the connection to the server has been broken unexpectedly. That is, we have called connect previously, it has succeeded, we have not called disconnect, and now the connection has been broken. Often we simply want to reconnect in the connectionLost callback
. The final callback function is deliveryComplete
, which is called when an MQTT publish exchange finishes. The MQTTClient_publish call blocks, but only until the publish packet is written to the socket. For QoS 0, this is the end of the story. For QoS 1 and 2, the MQTT packet exchange continues. When the final acknowledgement is received from the server, deliveryComplete
is called. context
is a pointer which is passed to the callbacks and can contain any useful information, such as the client object for which this callback is being made.
For this synchronous client, you do have the option of not setting any callbacks. In that case, no background thread will be started. Under these circumstances, the application, on a regular basis, must call
to receive messages, or
to allow any necessary MQTT background processing to take place. This mode was intended specifically when the application wanted no threads to be created.
Application Setup - MQTTAsync
The application setup for the asynchronous client library is very similar to the synchronous library. Header file:
client object creation:
and setting the callbacks:
There is no non-threaded mode for the async client, background threads will always be created and the arrival of MQTT publications will be notified by the messageArrived callback
.
How to Connect an MQTT Broker to Paho MQTT C Client?
To connect to a server, we create a connect options structure and call connect:
which will block until the MQTT connect is complete, or has failed. Similarly, for the async client:
except that we add two pointers to callback functions. The connect call will not block, success or failure will be notified by the invocation of one or other of the callback functions. For the other connect examples, I’ll just show the synchronous client, but the pattern is the same for the async client. A typical pattern for the async client is to make all MQTT calls in callback functions: a subscribe or publish call can be made in the success callback for connect, for instance.
Connect with LWT
Connect with Username and Password
Publishing a Message to a Topic Using Paho MQTT C Client
Publish looks like the following for the synchronous client:
There is also another version of the call which takes a message structure:
The delivery token can be used in a waitForCompletion call, to synchronize on the completion of the MQTT packet exchange. The async calls for publish look very similar, except I renamed publish to send, and topic to destination. This was to be compatible with the JavaScript Paho client, because the asynchronous programming models are very similar. It seemed like a good idea at the time!
Again, the biggest change is the addition of the success and failure callbacks.
Subscribing to a Message Using Paho MQTT C Client
The subscribe call is straightforward:
and for the async client:
Unsubscribing to a Message Using Paho MQTT C Client
The unsubscribe call is also straightforward:
and for the async client:
Disconnect
There is a timeout parameter in milliseconds on the disconnect call, which allows outstanding MQTT packet exchanges to complete.
or:
When you’ve finished with a client object, call destroy to free up the memory:
or:
Receiving Messages
A typical message arrived callback function might look like this:
Note the calls to free memory, and the return value: 1 means that the message was received properly, 0 means it wasn’t. The messageArrived callback
will be invoked again for the same message if you return 0.
Using TLS / SSL
To use TLS, you need to add the SSL options data to the connect options:
The TLS implementation uses OpenSSL, so the configuration parameters are the same:
Example Application of Paho MQTT C Client
Sample application for the Paho C clients are in the samples directory of the github repository and in the download packages.
Ian Craggs
Ian Craggs works for IBM, and has been involved with MQTT for more than 10 years. He wrote the IBM MQTT server Really Small Message Broker which became the inspiration for the Eclipse Mosquitto project. He contributed C client libraries to the Eclipse Paho project at its onset and is now the project leader.