Real-time Communication with MQTT
12 November 2019
Updated: 03 September 2023
Overview
MQTT is an open standard for communication and is especially useful for communication between IoT devices due to its low bandwidth requirements
Today we’re going to be taking a look at using MQTT to easily communicate between multiple applications. We’ll look at using a static website and Eclipse Mosquitto as a message broker to enable communication between two instances of the application, but the same principles can be extended to other programming languages and MQTT clients. For our clients we’ll be using MQTT.js
which runs in the browser via CDN and we interact with it using JavaScript, but can also be added from npm
If you’d like to follow along with the completed code you can get it here
Broker
Eclipse Mosquitto is an open-source (EPL/EDL licensed) message broker that implements the MQTT protocol versions 5.0, 3.1.1 and 3.1. Mosquitto is lightweight and is suitable for use on all devices from low power single board computers to full servers. (Eclipse Mosquitto )
Message brokers are a method of intra-application communication, MQTT makes use of a publish/subscribe model for application communication. In this model different applications, or clients, can publish messages to a topic which can then be picked up and operated on by any other applications that are subscribed to the topic
Setting Up the Broker
You will first need to download Mosquitto from here , all 1.5mb
of it, and run through the installer and then ensure that mosquitto
is in your path. If you need to know how to add something to your path take a look at this Gist . For a Windows 64 bit installation of Mosquitto you should add the following to your path C:\Program Files\mosquitto
The MQTT installation should include the following three commands
mosquitto
- This runs the MQTT server/brokermosquitto_pub
- A simple message publishermosquitto_sub
- A simple message subscriber
We can get more information by running either of the above commands with the --help
flag, e.g. mosquitto --help
Basic Messaging
- Let’s start the message broker in verbose mode by opening a new shell and running the
mosquitto -v
command, you should see some output like the following:
We can see from the above that the message broker is running on our local port 1883
- In a new shell, we can create a client which is subscribed to a topic. We’ll name this topic
messages
but it can be pretty much anything you want, to start the subscriber client we can runmosquitto_sub -t "messages" -v
, you won’t see any output in the subscriber shell as yet, but looking at the broker shell you should logging which says that a client was connected
- To publish a message open another shell and run
mosquitto_pub -t "messages" -m "This is my message!"
, in our subscriber shell we should see the following output:
And in the broker we’ll see the following:
When you’re done with this you can close the open shell windows
Broker with WebSockets
For our usecase, we will make use of WebSockets so we can communicate directly from the browser. When starting up the message broker we have the option to pass in a configuration file. Let’s create one that states the port and the protocol we would like to use. Create a new directory called mqtt
, and in it create a new file called mosquitto.conf
and place the following contents which simply tell it to listen on port 9001
and use the websockets
protocol
mosquitto.conf
If you’d like to know what else can be done in the configuration file you can read the documentation
We can start the broker again from the mqtt
directory using mosquitto -c mosquitto.conf -v
, this time we should see that it is running on 9001
with websockets
Now that we have configured the broker to use Web Sockets we can start connecting to it from a web page and publish some messages
Client
We’ll be using MQTT.js to connect to our message broker. MQTT.js is a simple MQTT Client Library for connecting to message brokers, we’ll be using it via CDN for the sake of simplicity and will also be using Materialize for our CSS because I’m not going to write a bunch of CSS and I don’t want this to look completely terrible
HTML
Let’s first setup the index.html
. It consists of a two-column layout with the following:
- Main Heading with a badge to indicate if we successfully connected to the broker
- Inputs to Publish Message
- Table of all received messages
- Materialize and MQTT.js files via CDN
- Script tag for all our JavaScript, because we don’t need two files for this
index.html
Running the Website
Since we are including resources from other domains your browser may have some issues with you using the ‘double click’ method of running the files, so we’re going to need to use a web server
A list of quick one-line web servers can be found on this Gist and if you’re using Visual Studio Code you can use the Live Server Extension
Connecting to the Message Broker
Now that we’re up and running we can connect to the broker that we set up previously. The Mosquitto Broker should be running on 127.0.0.1:9001
, using the mqtt
object that is exposed in the global space by MQTT.js
we can simply create an instance of the client in our <script>
section with:
This gives us a client
object that is the MQTT Client connected to our broker. Next, we need to set a handler for the connect
event which is when the client successfully connects to the message broker, we do this with the following code:
You can see that the client.on
function takes a callback, in which we tell our client to subscribe to the messages
topic as we did previously via the mosquitto_sub
, and then once it has successfully subscribed we change the badge status to indicate that we are connected
Since we have successfully subscribed the client to the broker we should be able to publish messages. We’ll do that using the data from the input fields in on the page and the Publish Message
button’s handler
Publishing Messages
Create a handler for the Publish Message
button called handleSubmit
, we’ve already referenced this in our button’s HTML. The handler simply needs to read the values from the input fields and call client.publish
with a stringified form of the data
The client.publish
function above takes in a topic
and message
as its inputs, in our case we want to publish to the messages
topic and we are publishing the JSON object as a string
Refreshing the page, entering some text into the fields and clicking the Publish Message
button should publish the message to the broker, we should see this in the message broker’s output
Now that we can publish messages to the topic, we will need to create a handler for the message
event which is triggered every time one of our subscribed topics has something published to it. We can do this again with the client.on
function:
Our message handler receives the topic
, which in our case will always be messages
and the message
which is a buffer of the data published to the topic, this will be the same data that we published using the client.publish
function, this time we read the JSON back into an object and add it to the messages table as HTML
You should be able to open a few different windows of the web page and they should all be able to Publish Messages to one another
What Next?
If you’re not familiar with message brokers this could be a lot to take in and that’s okay. I think playing around with the mosquitto_pub
and mosquitto_sub
tools can be helpful to get a more interactive feel for the way everything works. You can also just play with the MQTT.js code we used via your browser console and looking at the documentation on the website
If you want to take a look at a free instance of an MQTT Broker that you can play around with take a look at Cloud MQTT , and if you want to look at how you can take the concepts covered here today and play around with some IoT concepts as well then it may also be worth taking a look at this IBM Developer Tutorial using IBM Cloud and Watson IoT
If you’re interested in spinning up your own MQTT broker with custom functionality you can take a look at Mosca or get an even deeper understanding of the MQTT Protocol on IBM Developer
Conclusion
We’ve used a couple of different technologies and depending on your background you may not be familiar with everything here. The best thing I’d say to get to understand what we’ve covered would be to play around with the code as well as look at some of the other services and use-cases for message brokers and get a feel for what’s out there
Good luck
Nabeel Valley