3. Usage

3.1. Run Tornado server

Django-tornado-websockets provides an easy solution to run your Tornado server. When you add tornado_websockets to your INSTALLED_APPS, you obtain a new management command called runtornado:

$ python manage.py runtornado

3.2. Using WebSockets (server side)

It’s preferable to write your WebSocket applications in your views.py file.

3.2.1. Create a WebSocket

You should use the WebSocket class to use... WebSockets 🤔. It takes only one parameter and it’s the url. This url should be unique because it’s automatically adding a new handler to Tornado handlers (your_url <=> your_websocket):

from tornado_websockets.websocket import WebSocket

# Make a new instance of WebSocket and automatically add handler '/ws/my_ws' to Tornado handlers
my_ws = WebSocket('/my_ws')

3.2.2. Listening to an event

To listen an incoming event, you should use the @my_ws.on decorator (where my_ws is an instance of WebSocket) on a function or a class method.

Functions and class methods should take two named parameters:

  • socket: client who sent the event (instance of WebSocketHandlerWrapper),
  • data: data sent by the client (dictionary).

Note

If you are using this decorator on a class method (a wild self parameter appears!), you need to define a context for the WebSocket instance because @my_ws.on decorator can not know by itself what value self should take (or maybe I am doing it wrong?):

class MyClass(object):

    def __init__(self):
        my_ws.context = self

Usage example:

# On a function
@my_ws.on
def my_event(socket, data):
    print('Catch "my_event" event from a client')
    print('But I know this client, it is the one using this websocket connection: %s' % socket)


# On a class method
class MyClass(object):

    def __init__(self):
        # Do not forget the context, otherwise the `self` value for all class methods decorated by `@my_ws.on`
        # decorator will be `None`
        my_ws.context = self

    @wy_ws.on
    def my_other_event(self, socket, data):
        # `self` value is a MyClass instance due to `my_ws.context = self` in `__init__()` method
        print('Catch "my_other_event" from a client')
        print('And same as before, I know that this client is using this websocket connection: %s' % socket)

3.2.3. Emit an event

Warning

You can only emit an event in a function or method decorated by @my_ws.on decorator.

  • If you want to emit an event for all clients connected to your WebSocket application, you should use my_ws.emit method,
  • If you want to emit an event for the client that sent the event, you should use socket.emit method,
  • If you want to emit an event for a specific client, it’s not officially implemented but you can take a look at my_ws.handlers list. It contains all clients connected to your application, so you can use my_ws.handlers[0].emit method.

Usage example:

import time

from tornado_websockets.websocket import WebSocket

my_ws = WebSocket('/party')


class MyParty(object):

    def __init__(self):
        my_ws.context = self

    @my_ws.on
    def connection(self, socket, data):
        user = data.get('user')  # e.g. 'Robert'

        # Inform all users that Robert joined the party
        my_ws.emit('user_joined', {
            'message': 'Hey guys, %s just joined the party!' % user,
            'timestamp': time.time()
        })

        # Said welcome to Robert
        socket.emit('welcome', 'Welcome to the party %s!' % user)
        # is equivalent to
        socket.emit('welcome', {'message': 'Welcome to the party %s!' % user})

        # For the organiser (let's say the first guy who joined the party is the organiser)
        my_ws.handlers[0].emit('receive_client', {'user': user})

3.3. Using WebSockets (client side)

Todo

Develop a JavaScript library/wrapper and write this section.