tornado_websockets.websocket — Django-tornado-websockets 0.0.7 documentation

# Source code for tornado_websockets.websocket

    # coding: utf-8

    from six import string_types

    import tornado_websockets.exceptions
    import tornado_websockets.tornadowrapper
    import tornado_websockets.websockethandler

    class WebSocket(object):
        """
            Class that you should to make WebSocket applications 👍.
        """

        def __init__(self, url, add_to_handlers=True):
            self.events = {}
            self.handlers = []
            self.context = None

            self.namespace = url.strip()
            if self.namespace[:1] is not '/':
                self.namespace = '/' + self.namespace

            if add_to_handlers is True:
                tornado_websockets.tornadowrapper.TornadoWrapper.add_handlers([
                    ('/ws' + self.namespace, tornado_websockets.websockethandler.WebSocketHandler, {
                        'websocket': self
                    })
                ])

        def on(self, callback):
            """
                Execute a callback when an event is received from a client, should be used as a decorator for a function or a
                class method.

                Event name is determined by function/method ``__name__`` attribute.

                :param callback: Function or a class method.
                :type callback: Callable
                :return: ``callback`` parameter.

                :Example:
                     >>> ws = WebSocket('/example')
                     >>> @ws.on
                     ... def my_event(socket, data):
                     ...     print('Received "my_event" event from a client.')
            """

            if not callable(callback):
                raise tornado_websockets.exceptions.NotCallableError(callback)

            event = callback.__name__

            if self.events.get(event) is not None:
                raise tornado_websockets.exceptions.WebSocketEventAlreadyBinded(event, self.namespace)

            # print('-- Binding "%s" event for "%s" namespace with callback "%s"' % (event, self.namespace, callback))
            self.events[event] = callback
            return callback

        def emit(self, event, data=None):
            """
                Send an event/data dictionnary to all clients connected to your WebSocket instance.
                To see all ways to emit an event, please read « :ref:`emit-an-event` » section.

                :param event: event name
                :param data: a dictionary or a string which will be converted to ``{'message': data}``
                :type event: str
                :type data: dict or str
                :raise: :class:`~tornado_websockets.exceptions.EmitHandlerError` if not used inside :meth:`@WebSocket.on() <tornado_websockets.websocket.WebSocket.on>` decorator.
                :raise: :class:`tornado.websocket.WebSocketClosedError` if connection is closed.

                .. warning::
                    :meth:`WebSocket.emit() <tornado_websockets.websocket.WebSocket.emit>` method should be used inside
                    a function or a class method decorated by :meth:`@WebSocket.on()
                    <tornado_websockets.websocket.WebSocket.on>` decorator, otherwise it will raise a
                    :class:`~tornado_websockets.exceptions.EmitHandlerError` exception.
            """

            if not data:
                data = dict()

            # print('-- WebSocket.emit(%s, %s)' % (event, data))

            if not isinstance(event, string_types):
                raise TypeError('Event should be a string.')

            if not isinstance(data, string_types) and not isinstance(data, dict):
                raise TypeError('Data should be a string or a dictionary.')

            if not self.handlers:
                raise tornado_websockets.exceptions.EmitHandlerError(event, self.namespace)

            for handler in self.handlers:
                if not isinstance(handler, tornado_websockets.websockethandler.WebSocketHandler):
                    raise tornado_websockets.exceptions.InvalidInstanceError(
                        handler, 'tornado_websockets.websockethandler.WebSocketHandler')

                if isinstance(data, string_types):
                    data = {'message': data}

                handler.emit(event, data)