A simple MQTT to Websocket Bridge using Mosquitto and pywebsocket

UPDATE: I have now isolated the problems to 64 bit linux, the setup described here does work without using the standalone web server and using apache...just not on my main system!

Following on from my experiences installing and testing pywebsocket I now move to the main reason why I bothered...to create a bridge to allow a user to view a web page showing a live stream of MQTT messages.

It should be noted that despite making the effort to setup pywebocket with Apache this time I will be using the standalone web/websocket server provided with pywebsocket (standalone.py) as I'm still trying to debug why this code doesn't work with apache!

Screen shot of MQTT messages received via a websocket

<!--more-->

Server Side Code

On the server it is a simple matter of writing a websocket handler file in python to subscribe to an mqtt topic then stream the messages through the web socket. Here I use the python MQTT client library included with mosquitto.

I defined the callbacks required by mosquitto then pynotify,  websockettransfer_data(request) being where all the cool stuff happens, this function is called on connection to the web socket and then loops waiting for MQTT messages.

To use this code save it in your websocket handler folder was a file ending in _wsh.py then access it using the filename without the ending.

import mosquitto
from mod_pywebsocket import msgutil

#create global variable for the request object
#(Holds details of ws connection)
g_request = &quot;&quot;

#define callbacks for mosquitto
def on_connect(rc):
    print &quot;connected&quot;

def on_message(msg):
    global g_request
    #send mqtt message to socket using the connection specified in g_request
    msgutil.send_message(g_request, &quot;&lt;strong&gt;&quot; + msg.topic + &quot;&lt;/strong&gt; - &quot; + msg.payload + &quot;&quot;)

def on_subscribe(mid, granted_qos):
    print &quot;subscribe&quot;

#define callback for pywebsocket

#allows for extra handshaking
def web_socket_do_extra_handshake(request):
    pass  # Always accept.

#main web socket function called on starting connection
def web_socket_transfer_data(request):
    global g_request
    g_request=request

    #create mosquitto object
    mqttc = mosquitto.Mosquitto(&quot;python_sub&quot;)

    #assign callbacks
    mqttc.on_message = on_message
    mqttc.on_connect = on_connect
    mqttc.on_subscribe = on_subscribe

    #connect to mqtt broker on localhost
    mqttc.connect(&quot;127.0.0.1&quot;, 1883, 60, True)

    #subscribe to topic &quot;test&quot;
    mqttc.subscribe(&quot;test&quot;, 2)

    #keep web socket connected while mqtt is connected
    while mqttc.loop() == 0:
        pass

As already mentioned this code doesn't work when using pywebsocket with apache - to launch the included standalone webserver launch standalone.py with the following command (when in pywebsocket/src/mod_pywebsocket/):

python standalone.py -p 8080 -d &lt;web server root path&gt; -w &lt;websocket handler path&gt;

so in my case I use

python standalone.py -p 8080 -d /home/oliversmith/public_html/ -w /home/oliversmith/public_html/websock_handlers/

Front End

I used the same html file as detailed in my previous post, it's simply a matter of browsing to the appropriate url not forgetting that it's on port 8080 (or whatever port you define) to avoid conflicting with apache.

To send test MQTT messages I used the Java Client included in the ia92 package provided by IBM as pictured.

If anyone knows why this doesn't work with apache I would appreciate them telling me! At the moment I suspect it's some privileges thing but I may be wrong