Evothings does MQTT with VerneMQ or EMQTT

Göran KrampeBlogs, Tutorials

vernemq-logo-kvad
Tweet about this on TwitterShare on FacebookShare on LinkedInShare on Google+

This is a followup article to Evothings does MQTT with Bluemix. This time we make the same application run but using our own MQTT server, showing how to get going with both VerneMQ and EMQTT using a real certificate from Letsencrypt.org.

I also tried to use MQTT.js instead of the Paho library we used previously but I eventually gave up, for some reason I just couldn’t get it to connect. The Paho library is also about 5x smaller even when minified and the MQTT.js library is primarily written for NodeJS, so… at this point I conclude the Paho library is preferred.

Read the previous article first if you want some background information on MQTT, including an IoT protocol overview, I also found this presentation highly informative and a good summary.

Letsencrypt

In order to set up our own server talking MQTT over Secure Websockets we need a proper SSL certificate, not a self signed one. One can get one for free these days, for example from StartSSL, but the hip and cool way is to use the up and coming Letsencrypt service!

hip-and-cool

The official documentation probably works fine, but I ended up following this howto and it was really simple. I did this on my Debian 8 server:

First stop anything running on port 80 and 443. Then get letsencrypt:

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt

Next we let it create our cert, it will ask us some questions, most importanyly the ip name(s) we want the cert to be valid for and you can enter more than one name for your domain separated by spaces:

./letsencrypt-auto certonly

When all is done you should find your certificate files in /etc/letsencrypt/live/your.domain.com/. The certificate is good for 90 days, see instructions in the documentation for renewals.

Finally an easy and free way to get a proper cert!

Your own MQTT server

So we want to use our own MQTT server. There are plenty around and I ended up trying out both VerneMQ and EMQTT. They are very easy to get started with and both are written in Erlang which in my book means they are probably robust choices.

Let’s try EMQTT first. If you prefer VerneMQ, skip down to the next section, you only need one server :)

EMQTT

Just follow the instructions to download and unzip in your regular user home directory. Now we need to configure it for secure websockets using our new certificate. Bring up the file emqttd/etc/emqtt.config in your favorite editor and edit it as follows:

  1. In the Listeners-section I skipped regular http support by simply removing the whole existing “HTTP and WebSocket Listener” section.
  2. Then after finding out how to use separate cert and chain files I uncommented the “WebSocket over HTTPS Listener” section and changed the certificate settings to look like this:
    [
       {certfile, "etc/ssl/cert.pem"},
       {keyfile,  "etc/ssl/privkey.pem"},
       {cacertfile, "etc/ssl/chain.pem"}
    ]
    
  3. Save it!

The reason for this is that using only the fullchain/privkey files caused iOS to have connection issues although Android handled it just fine…

do not ask me

Finish it by copying the certificate files (not sure why it didn’t work for me first with original paths):

cd emqttd/etc/ssl
cp /etc/letsencrypt/live/your.domain.name/*.pem .

If all is well you can now start EMQTT by doing ./bin/emqttd start. It should reply with “emqttd is started successfully!”.

Then you can use ./bin/emqttd_ctl --help to find information on how to list clients, list topics, trace topics etc. Quite neat! To see that you have proper listeners running you can check with ./bin/emqttd_ctl listeners and of course you can also see the ports open by running sudo netstat -plnt or similar.

Note that out-of-the-box the configuration allows anonymous connections, which is just fine for our testing of course.

VerneMQ

Installing VerneMQ was also quite easy following the instructions. Then its time for configuration but if that page looks daunting this is what I ended up changing:

  1. Turn on anonymous access:
    allow_anonymous = on
    
  2. Add a listener for secure web sockets:
    listener.wss.default = 0.0.0.0:8083
    
  3. Add Letsencrypt certificate files:
    listener.wss.cafile = /etc/vernemq/fullchain.pem
    listener.wss.certfile = /etc/vernemq/cert.pem
    listener.wss.keyfile = /etc/vernemq/privkey.pem
    
  4. Finally it turns out we need to increase a limit to cater for the longer iOS device UUIDs:
    max_client_id_size = 40
    

Then we copy the cert files into /etc/vernemq/ and change owner to vernemq. Using the original paths may work if you fix permissions so that vernemq can read them, but I copied them to be sure:

cp /etc/letsencrypt/live/your.domain.name/*.pem /etc/vernemq/
chown vernemq:vernemq /etc/vernemq/*.pem

…and that should be it! Start it up using the proper service – it will not say anything if it succeeds so check with status afterwards to make sure its up:

root@padme:~# service vernemq start
root@padme:~# service vernemq status
pong
vernemq is running

If you get a warning about ulimit you probably need to raise your limits, but it still works for demo.

ulimits too low

If you want to check if it works, you can try the online demo from HiveMQ. Just enter your hostname, port and check the SSL checkbox, then click Connect. If it connects (you get a green circle instead of a red one) you can also test a bit of publish/subscribe to make sure it works :)

Client library

There are two MQTT client implementations in JavaScript, the “Paho” library which lives in the Eclipse Paho project and MQTT.js hosted and maintained on github. Both support the latest version of MQTT 3.1.1 and thus also websockets.

Previously we used the Paho library but in this article I wanted to try out MQTT.js. After fiddling with browserify (or webpack) and rewriting the example code to fit the API etc – I utterly failed to connect using that library, kinda felt like this guy:

failure

Obviously I must have missed some detail, but I really have no clue why it doesn’t want to connect. So for us, the Paho library is what we use and recommend. Paho is also much smaller and not primarily written for NodeJS, although I haven’t scrutinized the code quality of these two libraries.

The Painter Example

Our example app is the same as before – a trivial interactive painting app where the paint operations are shared over MQTT. Each user connects and subscribes to the same topic – and when a user is painting with the finger on the canvas we publish a simple JSON payload describing a painted line from (x,y) to (x2,y2) in a specific color, for each touchmove event.

When the app receives messages it paints them. Note that even the original painter will only paint the line when it’s received as a message. This means as the active painter you get a sense of the latency involved.

Running the app

Now let’s get our app running. I presume you have gotten started with Evothings Workbench, then you just need to:

  1. Git clone our demo repository to your laptop, or just download and unzip it.
  2. Locate the folder mqtt-vernemq-emqtt-painter and drag the index.html file from there and drop it onto the “My Apps” tab in the Workbench. It should then be added to the list.

Before starting the app you need to edit it and enter your own host and port – you don’t need to change user/password since we do not use it. Open the app.js file and modify lines 10-11 in app.js with the correct settings:

var host = 'padme.krampe.se'; // Change this to your server
var port = 8083; // No need to change this if you configured your server as described

Now if your Workbench is connected with one or more devices you should be able to just click the RUN button to get the app started.

The app should hopefully say “Connected!” on your device. Feel free to use the “CONNECT” button to reconnect if you are disconnected, at the moment the example does not try to keep the connection alive via ping. You can also open up the Javascript Workbench using the top right Tools-button. This enables you to see what the app is logging when its running.

Now start painting with your finger, each connected device should paint its own color.

painter1

Conclusion

MQTT is very easy to get going with and both VerneMQ and EMQTT are easy to install. Letsencrypt also makes it trivial to get your own real certificate which is highly recommended since mobile hybrid apps refuse to deal with self signed certificates. For a whole range of mobile IoT applications MQTT should be a very logical choice for communication, both between devices (mobile or IoT) and between devices and servers.

Hope you found this article interesting, download Evothings Studio today and start hacking your own MQTT powered app!

download