MQTT

In this series of post, I will explain how to use the message broker MQTT. From installation to submit and receive messages in Python and C++.

A bit of history

MQTT was created way back in 1999 by two engineers — Andy Stanford-Clark (IBM) and Arlen Nipper (Eurotech). They had to invent a new protocol for connecting oil pipelines over unreliable, satellite networks.

The motivation for designing MQTT was to create a lightweight and bandwidth-efficient protocol that was data agnostic with support for multiple levels of Quality of Service (QoS). Interestingly, even today, those are the same reasons for which MQTT is chosen for implementing IoT solutions.

In 2011, IBM and Eurotech donated MQTT to the proposed Eclipse project called Paho. In 2013, it was submitted to OASIS for standardization. The latest version of the protocol specification, 3.11 has become an OASIS standard.

(Source: Eurotech)

Server

There are many message brokers that implement MQTT in the market. Some of them you can use as a service (via Azure, Amazon, Scaleway, etc), some other you need to install them.

People familiar with Python might know RabbitMQ, a general purpose message broker that contains a plug-in to operate an MQTT service.

Before going forward, we need to consider that MQTT supports only the pub-sub messaging technique. It is useful in cases where messages are short-lived, and there is active-routing of connected subscribers and publishers. Thus, it is troublesome to use MQTT for the classical long-lived messaging queues.

On the other hand, RabbitMQ supports almost all the messaging forms like pub-sub, round-robin, message-queues, etc. It also supports message grouping and idempotent messages. It supports a lot of fine-grain control in terms of accessing queues. One can restrict access to certain queues, manage the depth and a lot more.

Because of that, I decided to use a simple version of MQTT from Eclipse: Mosquitto

Installation

We can deploy a mosquitto server using Docker:

docker create --name mosquitto-test -it --net host eclipse-mosquitto
98b31b1bef35d915b291ba190add1fb03bbe0a135685ff93034078cb6d704d7c

and now we start the service

docker start mosquitto-test
mosquitto-test

We can check that the server is running checking its logs

docker logs mosquitto-test
1617438367: mosquitto version 2.0.9 starting
1617438367: Config loaded from /mosquitto/config/mosquitto.conf.
1617438367: Starting in local only mode. Connections will only be possible from clients running on this machine.
1617438367: Create a configuration file which defines a listener to allow remote access.
1617438367: Opening ipv4 listen socket on port 1883.
1617438367: Opening ipv6 listen socket on port 1883.
1617438367: Error: Address not available
1617438367: mosquitto version 2.0.9 running

Testing

For this test, we will need to open two consoles: In the first place, one to execute the command to receive messages (mosquitto_sub) and in the second place, we send the messages.

Do not revert the order, as by default messages in mosquitto are not persistent, and if you publish and nobody was subscribed to that topic, the message is lost.

The result should look like

(base) luis@BARE:~$ docker exec mosquitto-test mosquitto_sub -h localhost -t hello/world -d
Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending SUBSCRIBE (Mid: 1, Topic: hello/world, QoS: 0, Options: 0x00)
Client (null) received SUBACK
Subscribed (mid: 1): 0
Client (null) received PUBLISH (d0, q0, r0, m0, 'hello/world', ... (11 bytes))
Hello world
^C
(base) luis@BARE:~$ 
#Sending messages 
docker exec mosquitto-test mosquitto_pub -h localhost -m 'Hello world' -t hello/world -d
Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending PUBLISH (d0, q0, r0, m1, 'hello/world', ... (11 bytes))
Client (null) sending DISCONNECT