Sunday, October 02, 2011

Simple websocket push service using Tornado

WebSocket server side documentation/guides around tend to be very node.js oriented. However, I don't fancy rewriting stuff I already have simply to be able to make use of WebSocket. After some research, I figured out a mechanism for a service which will handle push for WebSocket, in a simpler manner which are familiar to everyone - simple POST/GET!

Example server code: (on Tornado 11.0)

import tornado.ioloop
import tornado.web
from tornado import websocket

GLOBALS={
    'sockets': []
}

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

class ClientSocket(websocket.WebSocketHandler):
    def open(self):
        GLOBALS['sockets'].append(self)
        print "WebSocket opened"

    def on_close(self):
        print "WebSocket closed"
        GLOBALS['sockets'].remove(self)

class Announcer(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        data = self.get_argument('data')
        for socket in GLOBALS['sockets']:
            socket.write_message(data)
        self.write('Posted')

application = tornado.web.Application([
    (r"/", MainHandler),
    (r"/socket", ClientSocket),
    (r"/push", Announcer),
])

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

Example Client Javascript (jQuery)

$(document).ready(function () {
    var ws = new WebSocket("ws://localhost:8888/socket");
    ws.onmessage = function(event) {
       $('body').append('<div>' + event.data + '</div>');
    }
    $('body').append('<div> Start! </div>');
});

How to try

Start the Tornado server, load http://localhost:8888/push?data=somedatahere. This will send 'somedatahere' to the websockets and notify them all with the string.

Probably this can evolve to a nicer service system. But I'll hack on it more later
Post a Comment