mqtt and NodeJS

mqtt is a lightweight publish/subscribe protocol often used for connecting devices in the Internet Of Things (IoT) world. There are competing protocols but some larger players, like for instance Amazon IoT, supports mqtt.

This post shows how to setup a mqtt server using docker and NodeJS. It is also fairly easy to setup a load balanced pool of mqtt servers behind haproxy. This also shown.

Getting started

Some notes about running a mqtt server and client in docker using nodejs.

  1. Install and start a nodejs docker container using docker-nodejs

  2. In the container, change node version: nvm install v0.12.9; nvm alias default v0.12.9

  3. Install dependencies: apt install -y libzmq-dev libkrb5-dev

  4. Install mqtt server: cd /apps; npm install mosca bunyan

  5. Start the mosca mqtt server in the foreground: ./node_modules/mosca/bin/mosca -v | ./node_modules/bunyan/bin/bunyan. Disconnect with ctrl-p ctrl-q.

  6. Install a mqtt client: npm install mqtt -g. You need to install NodeJS on your local machine first. I'd suggest you use nvm to manage NodeJS versions.

  7. Check the IP of the docker server. I'm using docker-machine to manage docker on my laptop: docker-machine ls

  8. Subscribe (replace the IP-address with your docker server IP): mqtt sub -t 'hello' -h '' -v

  9. In another terminal, publish a message (replace the IP-address with your docker server IP): mqtt pub -t 'hello' -h '' -m 'from MQTT.js'

  10. You should see the message in the terminal where you are subscribing! mqtt.js can be used from browsers (and therefore also with Cordova when developing mobile apps) and is also possible to use together with the excellent module manager browserify.

Using with haproxy as load balancer

haproxy is a open source load balancer that is commonly used.

  1. Install haproxy in a docker container using docker-haproxy

  2. Check the IP-address of the docker container running mosca (stop the server and run ifconfig and then start it again).

  3. If you're on a laptop, then you can setup an entry in /etc/hosts. On servers, setup the DNS as usual.

  4. Setup a frontend and backend in haproxy for the mosca server. Use the same configuration as for any http(s) backend. The docker-haproxy repo has a template that can be used.

  5. Subscribe: mqtt sub -t 'hello' -h 'mqtt.gizur.local' -v

  6. Publish: mqtt pub -t 'hello' -h 'mqtt.gizur.local' -m 'from MQTT.js'

  7. You should see the message in the terminal, just like before. The difference is that now we can add several mqtt servers behind the haproxy load balancer!

Another nice feature is that haproxy can be used to terminate SSL. This way SSL is used between the mqtt client and haproxy and simple TCP/HTTP used between haproxy and the server behind.

This command will subscribe using TLS: mqtt sub -t 'hello' -h 'mqtt.gizur.local' -p 8883 -m -C 'tls' --insecure. We accept self-signed certificates here. Remove --insecure when testing production environments.

This command will publish using TLS: mqtt pub -t 'hello' -h 'mqtt.gizur.local' -p 8883 -m 'from MQTT.js' -C 'tls' --insecure