3. Usage — Django-tornado-websockets 0.0.7 documentation

# 3. Usage

- Run Tornado server
- Using WebSockets (server side)
  - Create a WebSocket
  - Listening to an event
  - Emit an event
- Using WebSockets (client side)

## 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.