Pyramid SockJS

Pyramid SockJS

Overview

Gevent-based SockJS integration for Pyramid. SockJS interface is implemented as pyramid route. It runs inside wsgi app rather than wsgi server. It’s possible to create any number of different sockjs routes, ie /__sockjs__/* or /mycustom-sockjs/*. also you can provide different session implementation and management for each of sockjs routes.

Gevent based server is required for pyramid_sockjs. For example gunicorn with gevent worker. pyramid_sockjs provides simple paster server runner:

1
2
3
4
[server:main]
use = egg:pyramid_sockjs#server
host = 0.0.0.0
port = 8080

Example of sockjs route:

def main(global_settings, **settings):
    config = Configurator(settings=settings)
    config.add_sockjs_route()

    return config.make_wsgi_app()

By default add_sockjs_route() directive creates sockjs route with empty name and prefix /__sockjs__, so js client code should look like:

<script src="http://cdn.sockjs.org/sockjs-0.2.min.js"></script>
<script>
    var sock = new SockJS('http://localhost:8080/__sockjs__');

    sock.onopen = function() {
      console.log('open');
    };

    sock.onmessage = function(obj) {
      console.log(obj);
    };

    sock.onclose = function() {
      console.log('close');
    };
</script>

All interactions between client and server happen through Sessions. Its possible to override default session with custom implementation. Default session is very stupid, its even not possible to receive client messages, so in most cases it is required to replace session. Let’s implement echo session as example:

from pyramid_sockjs.session import Session

class EchoSession(Session):

    def on_open(self):
        self.send('Hello')
        self.manager.broadcast("Someone joined.")

    def on_message(self, message):
        self.send(message)

    def on_close(self):
        self.manager.broadcast("Someone left.")

To use custom session implementation pass it to add_sockjs_route() directive:

def main(global_settings, **settings):
    config = Configurator(settings=settings)

    config.add_sockjs_route(session=EchoSession)

    return config.make_wsgi_app()

Sessions are managed by SessionManager, each sockjs route has separate session manager. Session manage is addressed by same name as sockjs route. To get session manager use get_sockjs_manager() request function.

def main(...):
    ...
    config.add_sockjs_route('chat-service')
    ...
    config.add_route('broadcast', '/broadcast')
    ...
    return config.make_wsgi_app()


@view_config(route_name='broadcast', renderer='string')
def send_message(request):
    message = request.GET.get('message')
    if message:
       manager = request.get_sockjs_manager('chat-service')
       for session in manager.active_session():
           session.send(message)

    return 'Message has been sent'

To use custom SessionManager pass it as session_manager= argument to add_sockjs_route() configurator directive. Check pyramid_sockjs.Session and pyramid_sockjs.SessionManager api for detailed description.

Supported transports

Limitations

Pyramid sockjs does not support multple websocket session with same session id.

gevent does not support Python 3

Examples

You can find them in the examples repository at github.

https://github.com/fafhrd91/pyramid_sockjs/tree/master/examples

License

pyramid_sockjs is offered under the BSD license.

Installation

virtualenv

  1. Install virtualenv:

    $ wget https://raw.github.com/pypa/virtualenv/master/virtualenv.py
    $ python2.7 ./virtualenv.py --no-site-packages sockjs
    
  2. Install gevent 1.0b2 (non-Windows users):

    $ ./sockjs/bin/pip install http://gevent.googlecode.com/files/gevent-1.0b2.tar.gz
    
  1. Install gevent 1.0b2 (Windows users, presuming you are running 32bit Python 2.7):

    $ ./sockjs/Scripts/easy_install http://gevent.googlecode.com/files/gevent-1.0b2-py2.7-win32.egg
    
  2. Clone pyramid_sockjs from github and then install:

    $ git clone https://github.com/fafhrd91/pyramid_sockjs.git
    $ cd pyramid_sockjs
    $ ../sockjs/bin/python setup.py develop
    

Server config

To use gevent based server use following configuration for server section:

[server:main]
use = egg:pyramid_sockjs#server
host = 127.0.0.1
port = 8080

To use gunicorn server use following configuation for server section, gunicorn 0.14.3 or greater is required:

[server:main]
use = egg:gunicorn
host = 127.0.0.1
port = 8080
workers = 1
worker_class = gevent

Chat example

You can run chat example with following command. It doesnt require any configuration, it runs on host 127.0.0.1 and port 8080:

$ ./sockjs/bin/python ./pyramid_sockjs/examples/chat.py

API

Session states:

STATE_NEW
STATE_OPEN
STATE_CLOSING
STATE_CLOSED

Indices and tables