Search code examples
pythonwebsockettornado

Keeping a list of websocket connections in Tornado


I figured to keep track of multiple websocket connections I have to store the WebSocket Handler objects in a list. But I have multiple handlers - one for each WS URI (endpoint). Lets say my project has three end points - A, B, C

ws://www.example.com/A
ws://www.example.com/B
ws://www.example.com/C

So to handle connections for each of these, I have three handlers. So I am puzzled about where to create the list to store the handler objects to be used later.

My code before adding the list is --

class WSHandlerA(tornado.websocket.WebSocketHandler):
    def open(self):
        print 'new connection'
        self.write_message("Hello World")

    def on_message(self, message):
        print 'message received %s' % message

    def on_close(self):
        print 'connection closed'


class WSHandlerB(tornado.websocket.WebSocketHandler):
    def open(self):
        print 'new connection'
        self.write_message("Hello World")

    def on_message(self, message):
        print 'message received %s' % message

    def on_close(self):
        print 'connection closed'

class WSHandlerC(tornado.websocket.WebSocketHandler):
    def open(self):
        print 'new connection'
        self.write_message("Hello World")

    def on_message(self, message):
        print 'message received %s' % message

    def on_close(self):
        print 'connection closed'

application = tornado.web.Application([
    (r'/A', WSHandlerA),
    (r'/B', WSHandlerB),
    (r'/C', WSHandlerC),
])


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

So where do I create this list and make sure it's visible to all the objects created? I am new to python as well and so having a little trouble wrapping my head around it.

I also realize I could probably use just one URI (endpoint) and send the multiple commands as part of the message itself. But then I don't want to turn WebSocket into a binary protocol. Given that we have URIs I should be using them.

Thanks for any help.


Solution

  • It depends what you want to do with the handlers, but you could easily make them accessible in three lists:

    # Global variables.
    a_handlers = []
    b_handlers = []
    c_handlers = []
    

    WSHandlerA.open() does a_handlers.append(self), and WSHandlerB.open() does b_handlers.append(self), and so on. WSHandlerA.on_close() does a_handlers.remove(self).

    If you want to do something with all A handlers:

    for handler in a_handlers:
        handler.write_message("message on A")
    

    To do something with all handlers:

    for handler in a_handlers + b_handlers + c_handlers:
        # do something....
        pass
    

    By the way, if you use a Python set() instead of a list for each set of handlers it'll be a little better. With sets instead of lists, use add and discard instead of append and remove.