flaviogrossi / sockjs-cyclone

SockJS server support for the Cyclone web server
MIT License
26 stars 4 forks source link
cyclone python sockjs sockjs-server twisted websocket

.. contents:: Table of contents

SockJS-cyclone

.. image:: https://badge.fury.io/py/sockjs-cyclone.png :target: https://pypi.python.org/pypi/sockjs-cyclone

.. image:: https://secure.travis-ci.org/flaviogrossi/sockjs-cyclone.png?branch=master :target: http://travis-ci.org/#!/flaviogrossi/sockjs-cyclone

.. image:: https://pypip.in/d/sockjs-cyclone/badge.png :target: https://crate.io/packages/sockjs-cyclone/

.. image:: http://img.shields.io/badge/license-MIT-blue.svg :target: http://opensource.org/licenses/MIT

SockJS-cyclone is a pure Python server implementation for the SockJS client library <https://github.com/sockjs/sockjs-client> running on the Cyclone <http://cyclone.io> web server.

SockJS-cyclone is released under the MIT license <https://github.com/flaviogrossi/sockjs-cyclone/tree/master/LICENSE>_.

What is SockJS?

SockJS <http://sockjs.org>_ is a browser JavaScript library that provides a WebSocket-like object. SockJS gives you a coherent, cross-browser, JavaScript API which creates a low latency, full duplex, cross-domain communication channel between the browser and the web server, which consistently works across old browsers, misconfigured or old proxies and firewalls, etc. by automatically using other transports as a fallback mechanism.

SockJS main features:

SockJS-cyclone fully supports the SockJS protocol version 0.3.3.

What is Cyclone?

Cyclone <http://cyclone.io>_ is a very fast and scalable web server framework that implements the Tornado API as a Twisted protocol.

How does it look like?

A live demo deployed on Heroku can be found here <http://sockjs-cyclone-demo.herokuapp.com>_.

Here is a small example for an echo server:

.. code-block:: python

from twisted.internet import reactor
import cyclone
import sockjs.cyclone

class EchoConnection(sockjs.cyclone.SockJSConnection):
    def messageReceived(self, message):
        self.sendMessage(message)

if __name__ == "__main__":
    EchoRouter = sockjs.cyclone.SockJSRouter(EchoConnection, '/echo')
    app = cyclone.web.Application(EchoRouter.urls)
    reactor.listenTCP(8888, app)
    reactor.run()

and an excerpt for the client:

.. code-block:: javascript

var sock = new SockJS('http://mydomain.com/echo');
sock.onopen = function() {
    console.log('open');
};
sock.onmessage = function(e) {
    console.log('message', e.data);
};
sock.onclose = function() {
    console.log('close');
};
sock.send('hello!');

Complete examples can be found here <https://github.com/flaviogrossi/sockjs-cyclone/tree/master/examples>_.

Multiplexing

SockJS-Cyclone supports multiplexing (multiple distinct channels over a single shared connection):

.. code-block:: python

from twisted.internet import reactor
import cyclone
from sockjs.cyclone.conn import SockJSConnection, MultiplexConnection
from sockjs.cyclone.router import SockJSRouter

class AnnConnection(SockJSConnection):
    def messageReceived(self, message):
        self.sendMessage('Ann received ' + message)

class BobConnection(SockJSConnection):
    def messageReceived(self, message):
        self.sendMessage('Bob received ' + message)

class CarlConnection(SockJSConnection):
    def messageReceived(self, message):
        self.sendMessage('Carl received ' + message)

if __name__ == "__main__":
    multiplexConnection = MultiplexConnection.create(ann=AnnConnection,
                                                     bob=BobConnection,
                                                     carl=CarlConnection)

    echoRouter = SockJSRouter(multiplexConnection, '/echo')

    app = cyclone.web.Application(echoRouter.urls)
    reactor.listenTCP(8888, app)
    reactor.run()

See the websocket-multiplex <https://github.com/sockjs/websocket-multiplex> library for the client support, and the complete example <https://github.com/flaviogrossi/sockjs-cyclone/tree/master/examples/multiplex>.

Installation

Install from pypi with:

::

pip install sockjs-cyclone

or from the latest sources with:

::

git clone https://github.com/flaviogrossi/sockjs-cyclone.git
cd sockjs-cyclone
python setup.py install

SockJS-cyclone API

The main interaction with SockJS-cyclone happens via the two classes SockJSRouter and SockJSConnection.

SockJSConnection

The SockJSConnection class represent a connection with a client and contains the logic of your application. Its main methods are:

SockJSRouter

The SockJSRouter class routes the requests to the various connections according to the url prefix. Its main methods are:

Deployment

SockJS servers are usually deployed in production behind reverse proxies and/or load balancers. The most used options are currently Nginx <http://nginx.org> and HAProxy <http://haproxy.1wt.eu>.

For Heroku deployment, see the quickstart instructions here <https://github.com/flaviogrossi/sockjs-cyclone_heroku_quickstart>_.

Nginx

Two major options are needed to fully support proxying requests to a SockJS-Cyclone server: setting the HTTP protocol version to 1.1 and passing upgrade headers to the server <http://nginx.org/en/docs/http/websocket.html>_. The relevant portion of the required configuration is:

::

server {
    listen       80;
    server_name  localhost;

    location / {
        proxy_pass          http://<sockjs_server>:<port>;
        proxy_http_version  1.1;
        proxy_set_header    Upgrade $http_upgrade;
        proxy_set_header    Connection "upgrade";
        proxy_set_header    Host $http_host;
        proxy_set_header    X-Real-IP $remote_addr;
    }

}

For websocket support, nginx version 1.3.13 or above is needed.

A working nginx.conf example can be found in the examples directory <https://github.com/flaviogrossi/sockjs-cyclone/tree/master/examples/deployment>_.

HAProxy

A complete example for HAProxy deployment and load balancing can be found on SockJS-Node Readme <https://github.com/sockjs/sockjs-node#deployment-and-load-balancing>_.

Credits

Thanks to: