When I wrote about the HiveMQ MQTT broker I said it had a killer-feature: support for Websockets. I’ll admit to have been pestering Roger Light, creator of Mosquitto, so much that to shut me up (I think) he’s been adding support for Websockets into the Mosquitto broker!

This makes using MQTT even more fun.

Mosquitto and Websockets

Websocket support must be explicitly enabled when building Mosquitto, and building requires libwebsockets. Once enabled, we can add listeners with the websocket protocol. For example, this mosquitto.conf provides a default MQTT listener on port 1883, and two Websocket listeners, one with TLS, one without:

autosave_interval 1800
persistence true
persistence_file m2.db
persistence_location /var/mosquitto/
connection_messages true
log_timestamp true

acl_file /etc/mosquitto/jp.acl
password_file /etc/mosquitto/jp.pw

listener 1883

listener 9001 127.0.0.1
protocol websockets

listener 9002 127.0.0.1
protocol websockets
cafile /etc/mosquitto/tls/ca.crt
certfile /etc/mosquitto/tls/tiggr.ww.mens.de.crt
keyfile /etc/mosquitto/tls/tiggr.ww.mens.de.key

(In case you’re interested, I create the X.509 certificates for TLS using generate-CA.sh from the OwnTracks project.)

Mosquitto ACLs work for Websockets just as they do for MQTT publishes & subscribes; when accessing the broker via Websockets a different TCP transport channel is used – everthing else remains the same.

Using the Paho MQTT JavaScript client, we can create something like this which shows messages published to the Mosquitto broker as soon as they’re received.

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Mosquitto Websockets</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="mqttws31.js" type="text/javascript"></script>
    <script src="jquery.min.js" type="text/javascript"></script>
    <script src="config.js" type="text/javascript"></script>

    <script type="text/javascript">
    var mqtt;
    var reconnectTimeout = 2000;

    function MQTTconnect() {
        mqtt = new Messaging.Client(
                        host,
                        port,
                        "web_" + parseInt(Math.random() * 100,
                        10));
        var options = {
            timeout: 3,
            useSSL: useTLS,
            cleanSession: cleansession,
            onSuccess: onConnect,
            onFailure: function (message) {
                $('#status').val("Connection failed: " + message.errorMessage + "Retrying");
                setTimeout(MQTTconnect, reconnectTimeout);
            }
        };

        mqtt.onConnectionLost = onConnectionLost;
        mqtt.onMessageArrived = onMessageArrived;

        if (username != null) {
            options.userName = username;
            options.password = password;
        }
        console.log("Host="+ host + ", port=" + port + " TLS = " + useTLS + " username=" + username + " password=" + password);
        mqtt.connect(options);
    }

    function onConnect() {
        $('#status').val('Connected to ' + host + ':' + port);
        // Connection succeeded; subscribe to our topic
        mqtt.subscribe(topic, {qos: 0});
        $('#topic').val(topic);
    }

    function onConnectionLost(response) {
        setTimeout(MQTTconnect, reconnectTimeout);
        $('#status').val("connection lost: " + responseObject.errorMessage + ". Reconnecting");

    };

    function onMessageArrived(message) {

        var topic = message.destinationName;
        var payload = message.payloadString;

        $('#ws').prepend('<li>' + topic + ' = ' + payload + '</li>');
    };


    $(document).ready(function() {
        MQTTconnect();
    });

    </script>
  </head>
  <body>
    <h1>Mosquitto Websockets</h1>
    <div>
        <div>Subscribed to <input type='text' id='topic' disabled />
        Status: <input type='text' id='status' size="80" disabled /></div>

        <ul id='ws' style="font-family: 'Courier New', Courier, monospace;"></ul>
    </div>
  </body>
</html>

I’ve put the source to this simple example on Github, and I’ve verified it works with Safari, Chrome, and FireFox.

Demo

Instead of writing your own Web application, you can easily use the mqtt.io or the HiveMQ Websocket clients; configure them to use the host name and TCP port number (from the listener directive) of your Mosquitto broker.

Mosquitto with Websocket support should be with you very soon, and I hope you’ll agree with me, that this is very good news. :-)