Skip to content

Instantly share code, notes, and snippets.

@narutaro
Last active December 4, 2021 01:37
Show Gist options
  • Save narutaro/6461c0524f7d7ff01e21c2ecb0be84ca to your computer and use it in GitHub Desktop.
Save narutaro/6461c0524f7d7ff01e21c2ecb0be84ca to your computer and use it in GitHub Desktop.
MQTT in your browser

MQTT in your browser

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 the pub and 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 work as sensors which do publish and subscription

That's it for today, see you later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment