This post offers an introduction to the MQTT (Message Queuing Telemetry Transport) protocol  and also demonstrates its usage with an example in Python (Just for info: telemetry means the collection of measurement data from a remote location and its transmission wiki-link).
What is MQTT?
MQTT is a communication protocol which is actually developed for low-energy devices to transmit data with the low-bandwidth network.
It is a lightweight protocol built on the top of TCP/IP.
Lightweight: In software/programs, lightweight specify the characteristic of low memory and CPU usage.
MQTT allows simple and efficient data transmission from sensors to IoT (Internet of Things) networks. Additionally, it also enables the easy integration of new sensors to the IoT network.
In MQTT, there are five main terminology
- Broker: It is the middleware between data sender (publisher) and data receiver (subscriber). You can consider it as a server which receives data from sender and forward it to the receiver.
- Publisher: In simple terms, you can think of a device which needs to send data to other parties. This device could be a sensor, laptop, and Raspberry pi board.
- Subscriber: It is the receiver of data sent by the publisher.
Topic: Publisher and Subscriber do not know each other directly. When the publisher sends some data to Broker, it associates that data with a
topic. The topic is a string in the format of hierarchy e.g.
sensor/room-1/temprature(it is just an example) where '/' is level separator and each string represents a level. You can define it as per your requirement. When the subscriber connects to the Broker, it specifies the topic in which it is interested in. Then, broker forward published messages to their corresponding subscribers on the basis of the topic. Here, you need to understand two operators
#. Before jumping to these operators, let's assume a scenario where we have four temperature sensors in four rooms. These sensors are sending their data with the following topics
Now, in order to receive data from all four rooms, subscribers need to subscribe to the above topics. One way of doing that is to subscribe to each topic separately. Another way is to use
+operator and simply subscribe to the topic
+operator here matches any single level (
+is known as a single-level wildcard). Therefore,
home\+\tempraturewill match any topic with three-level hierarchy starting with
home\and ending with
\temprature. Coming to second operator
#which matches multi-level in the topic. For instance,
home\#will match all the aforementioned four topics.
Let's say we have multiple sensors which are transmitting data with following topics
Which topic to subscribe to receive all data from class-1 ?
Which topic to subscribe to receive data from group-1?
Which topic to subscribe to receive data from entire school?
#operator can appear only once in a topic expression e.g.
A topic expression
#matches every topic hence subscriber to this topic will receive every message.
Message: It is simply the data which needs to be sent.
Demonstration of MQTT in Python
Now, we will see a python example of using MQTT protocol for transmitting data. We will use a python package paho-mqtt for creating publisher and subcriber. You can install it using following command
pip install paho-mqtt
Next, we need to set up a Broker. There are numerous option of this. You can either use a cloud-based broker or you can install a broker on a server in your network. There are multiple cloud services are available with can be used (Complete list of broker servers). I would like to mention MaqiaTTo which is a free cloud-based MQTT broker. It can be used for testing purpose. In this tutorial, however, we are going to set-up a broker in the network. We will use Mosquitto broker server.
Setting up Mosquitto Broker
Mosquitto is an open-source MQTT message broker. Following are the instructions for installing it on your systems.
Ubuntu Users: Run following commands
sudo apt-add-repository ppa:mosquitto- dev/mosquitto-ppa sudo apt-get update
- Mac Users: First install brew package manager using following command
/usr/bin/ruby \ -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Next, install Mosquitto
brew install mosquitto
Starting Mosquitto Server (Mac Users)
Now, we are going to start our MQTT broker. Run the following command
/usr/local/sbin/mosquitto -c /usr/local/etc/mosquitto/mosquitto.conf
On ubuntu following command can be used to start or stop Mosquitto
sudo systemctl (start|stop) mosquitto
Writing Publisher and Subscriber codes
Now, we will develop our publisher and subscriber. Following are the steps for developing publisher and subscriber in Python.
- Create client
- Connect to broker
- Publish/subscribe message
- Connect callback function
- Run the loop
Let's understand these steps in details. The first step is to create a client. For this, we will create a
Client object from
paho-MQTT python package. The second step connects to the broker. In our case, we are running the broker on the same machine, therefore, we specify the broker's IP as
127.0.0.1 and port as
1883 (default port for Mosquitto broker). In third step, you can publish or subcribe using
subscribe() function. Next, we need to write callback functions.
It needs a bit of explanation. Callback functions are functions which are executed on the occurrence of particular events. Followings are the table showing the event and their corresponding callback function
Let's take one example to understand it. When a client connects to the broker, the broker sends an ACK (acknowledgment) to the client. This event triggers the execution of a callback function
Running a loop: Why we need to start a loop?
When a publisher sends messages to the broker or subscriber receive messages from the broker, these messages are first stored in the buffer. Now, in order to process all messages (either for sending or receiving), we need to write a loop manually. Thanks to
paho-MQTT, it provides three functions for the same purpose, therefore, we don't need to write message processing loop. These functions are as following
- loop(): When you call this function, it will process any pending message sending or receiving action. This function waits for a particular time (you can specify using
timeoutparameter) for processing buffer for reading or sending a message. After, that its execution completes. Therefore, if you plan to use this function you need to call it regularly.
- loop_forever(): This function call results in indefinite execution of your program. This function automatically reconnects to the broker in case of disconnection. This function is blocking type function (you can understand it as an infinite for loop) and it returns when you
disconnectwith the broker.
- loop_start() & loop_stop():
loop_start()function starts a new background thread and that thread regularly execute
loop()function. You can stop this background thread using
As we have setup our broker server, now we move towards writing publisher code.
import paho.mqtt.client as MQTT # function def connect_msg(): print('Connected to Broker') # function def publish_msg(): print('Message Published') # Creating client client = mqtt.Client(client_id='publisher-1') # Connecting callback functions client.on_connect = connect_msg client.on_publish = publish_msg # Connect to broker client.connect("127.0.0.1",1883) # if you experience Socket error then replace above statement with following one # client.connect("127.0.0.1",1883,60) # Publish a message with topic ret= client.publish("house/light","on") # Run a loop client.loop()
The above code publishes a message
on with topic
house\light. In this code, we have written two functions
publish_msg (you can use any names for functions). We connected these functions to callback functions using
client.on_connect = connect_msg. We specified that
connect_msg function is callback function and it will be called when the
Connection ACK event occurs (events and their callbacks are given in the above table). In this program, we used the
loop function which process pending action (sending or receiving) and then returns.
As we have our publisher with topic
house\ligh topic, we now develop our subscriber for the same topic.
import paho.mqtt.client as MQTT #import the client # Function to process recieved message def process_message(client, userdata, message): print("message received " ,str(message.payload.decode("utf-8"))) print("message topic=",message.topic) print("message qos=",message.qos) print("message retain flag=",message.retain) # Create client client = mqtt.Client(client_id="subscriber-1") # Assign callback function client.on_message = process_message # Connect to broker client.connect(broker_address,1883,60) # Subscriber to topic client.subscribe("house/light") # Run loop client.loop_forever()
- MQTT Version 5.0. Edited by Andrew Banks, Ed Briggs, Ken Borgendale, and Rahul Gupta. 07 March 2019. OASIS Standard. https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html. Latest version: https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html.