Friday, September 20, 2013

MQTT over websockets with javascript apache and active mq

Reading up a big about MQTT I decided to set up a test bed to see how it works and if it lives up to it's potential. The use case was simple, I wanted to build a multi-user chat system that would use MQTT over websockets connected directly to an apache activemq server.

First off, I fired up an ec2 instance with ubuntu-13.04 and tried to apt-get activemq. It turns out, however, to use mqtt over websockets, you need version 5.9 of activemq. So I pulled a snapshot version of activemq. Enabling mqtt over websockets is a snap, you simply add the following configuration to your activemq.xml

<transportConnector name="mqtt+ws" uri="ws://"/>

Next, download the eclipse paho mqtt client. And create a web page to send traffic back and forth.

One last thing I did was install apache on the same server as the activemq instance. I did this to avoid any potential problems with same origin policies.

At this point I create a page that uses the mqtt client and I can publish and subscribe to messages that will get pushed real time to the browser. My example follows (note, the aws instance in the connect string is no longer valid, you need to use your own server :)

        <title>MQTT over websockets</title>
        <style type="text/css">
            #status {
                padding: 5px;
                display: inline-block;
            label, .label {
                display: inline-block;
                width: 100px;
            li {
                list-style: none;

                background: #fff;
                margin: 2px;
            ul {
                background: #eef;
            .disconnected {
                background-color: #f88;
            input {
                width: 400px;
            .connected {
                background-color: #8f8;

            #messagelist {
                width: 600px;
                height: 200px;
                overflow-y: scroll;
        <h1>Super simple chat</h1>
        <span class='label'>Status</span> <div id="status" class="disconnected">Pending</div>
        <form id='mainform' action="#">
            <label for="name">Name</label>
            <input id="name" name="name" type="text" width="40" value="anonymous"/> <br/>
            <label for="message">Message</label>
            <input id="message" name="message" type="text" width="200"/>
            <input id="submit" type="submit" value="go"/>

        <div id="messages"><ul id="messagelist">


    <script src="./mqttws31.js"></script>
    <script src="./jquery-1.10.2.js"></script>
    $(document).ready(function() {
        function doSubscribe() {


            var messageinput = $('#message');
            message = new Messaging.Message(messageinput.val());
            message.destinationName = "/can/"+$('#name').val();
            return false;

        function doDisconnect() {

        // Web Messaging API callbacks
        var onSuccess = function(value) {

        var onConnect = function(frame) {
            //var form = document.getElementById("example");
            //form.connected.checked= true;
        var onFailure = function(error) {

        function onConnectionLost(responseObject) {
            //var form = document.getElementById("example");
            //form.connected.checked= false;
            //if (responseObject.errorCode !== 0)

        function onMessageArrived(message) {
            $('#messagelist').prepend('<li>'+message.destinationName+ '->' +message.payloadString+'</li>');
            //var form = document.getElementById("example");
            //form.receiveMsg.value = message.payloadString;

        var client;
        var r = Math.round(Math.random()*Math.pow(10,5));
        var d = new Date().getTime();
        var cid = r.toString() + "-" + d.toString()

        client = new Messaging.Client("", 1884, cid );
        client.onConnect = onConnect;
        client.onMessageArrived = onMessageArrived;
        client.onConnectionLost = onConnectionLost;
        client.connect({onSuccess: onConnect, onFailure: onFailure});