Introduction
MQTT is probably best known as a lightweight messaging protocol implemented for small sensors, but there is actually a JavaScript implementation called MQTT.js
. It's a JavaScript implementation, so of course it works in a browser. I think it's a great option for front-end engineers who are working with MQTT/IoT-related projects (for example, creating a dashboard to visualize MQTT data). In this article, I'd like to write about what I did when I tried to connect MQTT.js
to the test server (broker) of Mosquitto™
.
Sample code
It's very simple, but the following code should work. You should see {"name": "sensor1", "temp": 10}
in your browser console. As a scenario, I made it so that sensor1
in floor1/room1
is sending the temperature. MQTT topics are generally hierarchical with /
.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MQTT</title>.
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
</head>
<body>
<script>
let client = mqtt.connect('wss://test.mosquitto.org:8081');
let topic = "floor1/room1"
let metric = '{"name": "sensor1", "temp": 10}'
client.subscribe(topic);
client.publish(topic, metric);
client.on('message', function (topic, message) { // message is Buffer
console.log(message.toString());
});
client.end();
</script>
</body
</html>
- When throwing MQTT from a browser, it is common to use
MQTT over WebSocket
since you can't throw it directly. - Therefore, the protocol specification in the URI should be
wss://test.mosquitto.org:8081
.
Publish periodically, like a sensor.
Change the code to send data periodically.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MQTT DASH</title>.
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
</head>
<body>
<script>
let client = mqtt.connect('wss://test.mosquitto.org:8081');
let topic = "floor1/room1"
client.subscribe(topic);
pubLoop = setInterval(() => {
const time = Date.now().toString();
const temp = Math.floor( Math.random() * 11 );
let metric = '{"time":' + time + ', "name": "sensor1", "temp":' + temp + '}'
client.publish(topic, metric);
}, 1000);
client.on('message', function (topic, message) { // message is Buffer
console.log(message.toString());
});
setTimeout(function() { clearInterval( pubLoop ); }, 10000); // stop after 10sec
</script>
</body>
</html>
Console output. Well, it's starting to look like sensor data.
{"time":1588127649527, "name": "sensor1", "temp":6}
{"time":1588127650532, "name": "sensor1", "temp":4}
{"time":1588127651530, "name": "sensor1", "temp":6}
{"time":1588127652529, "name": "sensor1", "temp":1}
{"time":1588127653531, "name": "sensor1", "temp":3}
{"time":1588127654530, "name": "sensor1", "temp":8}
{"time":1588127655528, "name": "sensor1", "temp":10}
{"time":1588127656529, "name": "sensor1", "temp":10}
{"time":1588127657530, "name": "sensor1", "temp":4}
It might be easier to separate pub
/ sub
.
It might be easier to separate pub / sub instances like this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MQTT DASH</title>.
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
</head>
<body>
<script>
let pub = mqtt.connect('wss://test.mosquitto.org:8081');
let sub = mqtt.connect('wss://test.mosquitto.org:8081');
let topic = "floor1/room1"
sub.subscribe(topic);
pubLoop = setInterval(() => {
const time = Date.now().toString();
const amp = Math.floor( Math.random() * 11 );
const tem = Math.floor( Math.random() * 11 );
const hum = Math.floor( Math.random() * 11 );
let metric = '{"time":' + time + ', "name": "sensor1", "amp":' + amp + ', "temp":' + tem + ', "hum":' + hum + '}'
pub.publish(topic, metric);
console.log("pub: " + metric);
}, 1000);
sub.on('message', function (topic, message) { // message is Buffer
console.log("sub: " + message.toString());
});
setTimeout(function() {
clearInterval( pubLoop );
pub.end();
sub.end();
}, 10000); // stop after 10sec
</script>
</body
</html>
Now your browser should look like it's doing a sensor-like MQTT pub/sub.
That's it for today, see you later.