- MQTT Over Websockets
- Building an MQTT Web Application
- Creating the HTML Page
- Styling the Web Application
MQTT is a machine-to-machine connectivity/communication protocol. So what does this mean? MQTT is used by machines (think computer programs) for the transfer of data (think messages). Although MQTT has several uses, it is exceptionally prominent in the Internet of Things. The technology suits IoT because it is exceptionally lightweight and provides the functionality to subscribe and publish messages. And, of course, it suits IoT because it is naturally a machine-to-machine network.
MQTT is used by The Things Network, who are building a global IoT network using LoRaWAN. In my job as a lecturer, I am supervising a group of students who are building an open LoRaWAN network in Dunedin City. In this project, we have implemented the open source LoRa Server, which also uses MQTT to publish and subscribe to IoT data.
To first understand what MQTT is used for, it is prudent to understand a typical IoT/LoRaWAN network. There are several components in a network:
- A node device: a small embedded device with a sensor (e.g., temperature sensor) which sends data using a LoRaWAN wireless chip
- A gateway device: similar to a WiFi access point which forwards data from nodes to a specific destination, usually a server
- A network server: a computer that manages devices (gateways and nodes) and processes data sent from devices (nodes)
- An application: a solution the end-user has to display data
I like to be explained things in layman terms. When I first witnessed MQTT I didn’t really understand how the technology worked, or how it was used. The technical jargon was intimidating! The important use of MQTT for clients is in the subscription of MQTT data from a server. For example, create a web application or mobile application that retrieves and displays node data. But how does it get the data? Answer: it subscribes to an MQTT topic that the server publishes.
I like to explain the MQTT protocol similar to FM radio. A client is similar to the radio you have in your car. It can tune frequencies to listen to specific radio stations. The IoT equivalent is a subscription to an MQTT topic, where you must tune to the MQTT server. The key aspect, MQTT publications are live - the same way the radio station is live. If you want to save the music that a radio station is playing, you must record it. MQTT subscription is the same!
The first thing we need is an MQTT library to build our client. Writing an MQTT client is greatly simplified by using a well-documented and thoroughly tested library. I mean, why re-invent the wheel, when a group of talented developers have already designed an excellent wheel!
MQTT Over Websockets
Building an MQTT Web Application
Create a folder structure
First, create a folder to house the web application. I have just created a folder on my desktop named:
mqtt-demo. Inside that folder I have created a selection of files required for this project:
demo.html: A HTML file containing the web page content and structure
style.css: A CSS style sheet to enhance the design on the web page
Creating the HTML Page
HTML: Creating a simple skeleton
To start we should create a simple skeleton HTML document. The structure is very simple. The
<head> element contains a title for the web page. The
<body> element contains two
<div> elements, one name wrapper and one named messages. The wrapper contains all the content on the page, while the messages will display the MQTT messages received.
HTML: Adding the required libraries and external files
In order to achieve a functioning web application, we must add a variety of libraries and external files to the HTML source code. Firstly, we should add the style sheet named
.js file that will provide MQTT subscription functionality. This file is retrieved from CDNJS. Thirdly, we need to add the
demo.js file that we just created. This file will host our code to connect to the MQTT broker.
The final header should look like the code snippet below:
HTML: Adding a simple HTML form to get MQTT broker information
Next, we will add a simple HTML form to allow input of essential MQTT configuration information. This form will have three boxes to enter in: 1) The hostname or IP address of the MQTT broker; 2) The port number for the MQTT broker; and 3) The topic to subscribe to. In addition, we are going to put in two buttons: 1) To connect to the server and subscribe to a topic; and 2) To disconnect from the server.
Below is a simple form that will get the job done. Note how default values have been added with the
value="property" syntax. This information will display by default in the form, but can just be overwritten by new content. The current default values are set to the Mosquitto MQTT test server, which is excellent to test if the MQTT subscription is working. Also, note how the default topic is set to a hashtag symbol (
#) - this is a wildcard and will subscribe to any topic provided by the MQTT broker.
The form is configured to send the MQTT configuration to the
demo.js file (covered in detail below). Specifically, when the Connect button is clicked it calls the
startConnect function and when the Disconnect button is clicked it called the
HTML: Adding a div for MQTT messages
We need one final addition to the HTML page: a location to write all MQTT messages received. It is a simple addition of a single
div element under the form. Take note that the
id for the
div is named
HTML: Final HTML page
The entire HTML page we have made so far is documented below:
Currently, our web application has no functionality! When you click either button it does nothing! And it is not exactly sleek! But we will fix both those issues in the next sections.
JS: Fetching the values from the form
The first step to connecting to an MQTT broker is to fetch the information supplied by the user in the HTML form. This is easy using the
document.getElementByID method. Luckily, we have already set the unique ID value in the HTML form, these were:
JS: Writing the
Now that we have the required variables we can begin writing the code for the MQTT subscription. The first thing we should do is generate a client ID value. This can essentially be any string of characters and/or numbers but it must be unique. We can simply leverage the
Math.random function to generate a random number and concatenate it to a string value of
"clientID_". This will result in something like:
We now have all the information required to connect to the MQTT broker: 1) The hostname/IP address; 2) The port number; and 3) The random clientID string. We can call the
Paho.MQTT.Client method using these three variables. To make sure we are passing an integer as the port number, simple intcast the variable
After the connection to the MQTT broker has been specified and the
client object created, we can set the callback handlers for the client. These functions will be called if something goes wrong; for example, if the connection to the MQTT broker is lost, or when an MQTT message has arrived. We will write these functions later.
Finally, we can specify the
client to connect. In this piece of code, we have an
onSuccess action. When the connection works, the
onConnect function is called. This will be where we subscribe to a specific topic.
One more thing, there is also an
onFailure action in the
onConnect function. When the connection fails, the messages div in the webpage will display an error to the user. This is a simple, no jQuery solution. Basically, the
document.getElementById("messages") will identify the messages div, the
.innerHTML += will append text to the div, and
'<span>ERROR: Connection to: ' + host + ' on port: ' + port + ' failed.</span><br/>' will print an error message which also documents the hostname/IP and port number.
console.log(message) solution. However, this is only displayed in the web browser console, which some end-users have no knowledge of. So instead, we will display the error message on the actual web page itself.
The final, completed,
startConnect function is displayed below. Not how we use the same
innerHTML += solution to display the connection information in the full example below. This, again, provides feedback to the end-user.
JS: Writing the
When writing the
startConnect function, we specified two callback functions. The first was the
onConnectionLost function. This code is specified so that in the event of a lost connection an event can be specified. Similar to the previous code, we are going to put in some code that will display an error message in the messages div. In the scenario where the exit code from the connection is not
0, we will also print the error the messages div.
JS: Writing the
When writing the
startConnect function, we specified two callback functions. The second was the
onMessageArrived function. This code is very important! This function is called every time that a message is received from the MQTT broker. Similar to the previous code, we are going to put in some code that will display the message in the messages div.
JS: Writing the
disconnect method on the
client and the MQTT connection will be closed. We will also print out a message in the messages div to inform the user.
demo.js file we have made so far is documented below:
Styling the Web Application
CSS: Styling the HTML page
As it currently stands, our web application has a nice form and the required functionality to connect, subscribe and display MQTT messages to the end-user. However, we should probably add a little style to make the page look better and make the messages easier to view and review.
The following CSS rules can be placed in the
style.css file. These are just simple CSS rules that will add a little style and can be modified based on your requirements. The following rules specify the Open Sans font and set a
wrapper div for the page to ensure it is centered and has a suitable width.
CSS: Styling the HTML form
The HTML form has a terrible default layout without some CSS rules. Listed below are some basic rules to enhance the style of the form.
CSS: Styling the messages div
Finally, the most important part of the web page style is the messages div. Without modification, it will print continuously to the bottom of the webpage and is difficult and messy to deal with the MQTT messages. These simple CSS rules will create a fixed sized block to display the messages, complete with a vertical scrollbar.
JS: Writing the
In the last section, we styled the messages div and made it scrollable. One more nice feature would be if the messages box scrolled when it is full.
Every time something is written to the messages div, simply put include the
updateScroll function after the append to the messages div.
The final result is a nicely contained scrollable box for all the MQTT messages.
In this tutorial, we have built a custom web application capable of MQTT subscription. Basically, this web application can be configured to connect to an MQTT broker, for example, The Things Network, and can receive data from LoRaWAN nodes. The final result of this project can be seen below:
This tutorial barely scratched the surface of building a robust web application for an Internet of Things application. However, we covered the fundamentals. From this knowledge, you could implement the same MQTT connection and subscription, but then use the MQTT message data to build a graph or map! As always, feel free to comment if you have any questions or feedback. If you are interested in a further tutorial that covers secure MQTT please leave a comment. Thanks!