Prerequisites
- Node.js: This is the runtime environment required to run JavaScript on the server side. Download it from the official Node.js website.
- NPM: Node.js’s package manager, which is used to install libraries like React. It comes bundled with Node.js.
- Docker: Docker is a platform for developing, shipping, and running applications inside containers. Download Docker from Docker's official site.
- Source Code: You can find the source code for this tutorial on GitHub.
Introduction
MQTT is a lightweight publish/subscribe messaging protocol. It is designed for ease of use and minimal resource consumption. This efficiency has contributed to its widespread adoption in the IoT (Internet of Things) domain.
The MQTT paradigm is simple. It contains a broker, publisher and subscriber.
The broker is responsible for managing the propagation of data from the publisher to the subscriber.
The publisher sends updates to the broker. You can have many publishers sending all sorts of data to the broker.
The subscriber is a client that wants to read values that the publisher is publishing to the broker. The publisher and the subscriber don’t need to know anything about each other. They are anonymous and they don’t interact with each other.
In general, the broker will receive a message from a publisher and immediately forward it to subscribers without storing it (forward & forget). Identification of messages is done by subscribing to a topic.
In the context of MQTT, the topic is like an address or a URL. The publisher will publish its data on a specific topic. On the other side, the subscriber will subscribe to that topic to get updates from the broker with any new data published on that specific topic.
It is possible to set QoS levels. levels. A publisher may send a message to a topic at a different QoS to a subscriber on the same topic. MQTT supports multiple levels, but in most cases, we are satisfied with level zero of quality of service, where the broker will deliver the message once, with no confirmation.
Prepare an MQTT Broker
First of all, we need a broker. Mosquitto is an open-source broker that implements MQTT protocol. It is lightweight and is suitable for use on all devices from low-power computers to full servers.
Mosquitto has a drop-in solution that can be easily deployed by Docker-compose:
services:
mosquitto:
image: eclipse-mosquitto:2.0.18
container_name: mqtt-broker
restart: always
volumes:
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf
ports:
- "1883:1883"
By default, the Mosquitto container creates a config file located in:
/mosquitto/config/mosquitto.conf
The config file can be modified by accessing the running docker container or attached from host like in our case. For our the local implementation, we will change the following settings:
listener 1883
allow_anonymous true
Implementing Publisher and Subscriber in Node.js
To interact with the broker, we need to create a new Node.js and install the MQTT library called mqtt
.
npm init -y # Automatically agree to default settings
npm install mqtt
We will use the library and implement a publisher called publisher.js
:
const mqtt = require("mqtt");
var client;
const topic = "temperature";
const brokerUrl = `mqtt://127.0.0.1:1883`;
function connectToBroker() {
client = mqtt.connect(brokerUrl, {
keepalive: 60,
clientId: "publisherId",
protocolId: "MQTT",
protocolVersion: 4,
clean: true,
reconnectPeriod: 1000,
connectTimeout: 30 * 1000,
});
client.on("error", (err) => {
console.log("Error: ", err);
client.end();
});
client.on("connect", () => {
console.log("Client connected to broker");
});
}
function publishMessage() {
// Publish a message every 3 seconds
setInterval(() => {
const temperature = (Math.random() * 100).toFixed(2);
client.publish(topic, temperature.toString());
console.log(`Sent temperature: ${temperature} on topic: ${topic}`);
}, 3000);
}
connectToBroker();
publishMessage();
By running the code above, the publisher will publish a random number in a loop every 3 seconds on a topic called temperature
.
For subscriber implementation, we will use the same library and create a new file called subscriber.js
:
const mqtt = require("mqtt");
var client;
const topic = "temperature";
const brokerUrl = `mqtt://127.0.0.1:1883`;
const clientOptions = {
keepalive: 60,
clientId: "subscriberUniqueClientId",
protocolId: "MQTT",
protocolVersion: 4,
clean: true,
reconnectPeriod: 1000,
connectTimeout: 30 * 1000,
}; // Client options for connecting to the broker
function connectToBroker() {
client = mqtt.connect(brokerUrl, clientOptions);
client.on("error", (err) => {
console.log("Error: ", err);
client.end();
});
client.on("connect", () => {
console.log("Client connected to broker");
});
}
function subscribeToTopic() {
client.subscribe(topic, (err) => {
if (!err) {
// Subscribe to the topic
client.on("message", (topic, message) => {
// Message is of type Buffer and needs to be converted into a string
console.log(
`Received message: ${message.toString()} from topic: ${topic}`
);
});
} else {
console.log(`Error subscribing to topic: ${topic}`);
}
});
}
connectToBroker();
subscribeToTopic();
By running the code above, the subscriber will subscribe on the topic “TEMPERATURE” and with each update write the current value in the console.
Summary
MQTT stands as a pivotal protocol in the IoT ecosystem, enabling lightweight, efficient publish/subscribe messaging across devices. This tutorial introduced MQTT's fundamental concepts, showcased how to set up Mosquitto as a broker, and demonstrated simple publisher and subscriber implementations in Node.js. The ease of integrating MQTT with Node.js makes it an ideal choice for developers looking to enhance their IoT solutions.
If this guide has helped you, consider sharing it with others who might find it beneficial. Your feedback and suggestions are always welcome, so please leave a comment below or reach out with your thoughts!