MQTT with RUST and NodeJs

Uncategorized
2.8k words

iot

Pre-requisite

You need to make sure that these are installed in your environment :

What is MQTT ?

MQTT (Message Queuing Telemetry Transport) is another messaging protocol designed to be lightweight so it can be used in IOT devices.

The basic idea is pub-sub, devices connected to a message broker and they exchange data by subscribing (to receive) or publishing (to broadcast).

You can read a more detailed info on what is MQTT in this link.

We are now going to simulate a MQTT connection, we will build 2 clients in RUST & NodeJs and a broker in NodeJs.

Message Broker

A message broker’s job is to coordinate who gets what message.

Start by creating a node js project

1
2
yarn init -y #or
npm init -y

now add aedes dependency who is going to be our MQTT message broker

1
2
yarn add aedes
#aedes version 0.51.0

now create src/index.js

1
2
3
4
5
6
7
8
const aedes = require("aedes")
const server = require("net").createServer(aedes().handle); //use node js builtin net to serve our MQTT server

const MQTT_PORT = 1884;

server.listen(MQTT_PORT, function(){
console.log("mqtt broker is running in port " + MQTT_PORT);
});

Client

Our clients will act as a subscriber and a publisher, we’ll build a subscriber in Rust and a publisher in NodeJs.

One of MQTT’s features is to be able to define a topic on the fly, so you don’t need to configure it in the broker to be able to send messages back and forth.

Rust

1
cargo new mqtt-client-subscriber

in src/main.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
use rumqttc::{MqttOptions, Client, QoS};
use std::time::Duration;
use std::thread;

//https://crates.io/crates/rumqttc
fn main() {
let mut mqttoptions = MqttOptions::new("rumqtt-sync", "localhost", 1884); //define it as defined in message broker

mqttoptions.set_keep_alive(Duration::from_secs(5));
let (mut client, mut connection) = Client::new(mqttoptions, 10);


thread::spawn(move || for i in 0..10 { //publish message 10 times
client.publish("presence", QoS::AtMostOnce, false, "hello I guess").unwrap();
thread::sleep(Duration::from_millis(100)); //delay it by 100ms
});

for (_i, notification) in connection.iter().enumerate() {
println!("Notification = {:?}", notification);
}
}

Nodejs

Create a new NodeJs project

1
2
3
4
yarn init -y

# then add mqtt dependency
yarn add mqtt

in src/index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const mqtt = require("mqtt");

const client = mqtt.connect("mqtt://localhost:1884");

client.on("connect", ()=> {
client.subscribe("presence", (err) => { //subscribe to presence topic
if (!err){
console.log("subscribed to presence");
} else {
console.log(err);
}
});
});

client.on("message", (topic, message) => {
console.log(message.toString());
});

now run the broker first then the NodeJs subscriber by running node src/index.js in each project & lastly the Publisher in Rust by running cargo run.

Conclusion

MQTT is lightweight, and it’s widely implemented in many programming languages and building apps for MQTT requires minimal effort.