sockjs-tornado¶
This is implementation of the SockJS realtime transport library on top of the Tornado framework.
Topics¶
Statistics¶
sockjs-tornado captures some counters:
Name | Description |
---|---|
Sessions | |
sessions_active | Number of currently active sessions |
Transports | |
transp_xhr | # of sessions opened with xhr transport |
transp_websocket | # of sessions opened with websocket transport |
transp_xhr_streaming | # of sessions opened with xhr streaming transport |
transp_jsonp | # of sessions opened with jsonp transport |
transp_eventsource | # of sessions opened with eventsource transport |
transp_htmlfile | # of sessions opened with htmlfile transport |
transp_rawwebsocket | # of sessions opened with raw websocket transport |
Connections | |
connections_active | Number of currently active connections |
connections_ps | Number of opened connections per second |
Packets | |
packets_sent_ps | Packets sent per second |
packets_recv_ps | Packets received per second |
Stats are captured by the router object and can be accessed through the stats property:
MyRouter = SockJSRouter(MyConnection)
print MyRouter.stats.dump()
For more information, check stats module API or stats sample.
Frequently Asked Questions¶
How fast is sockjs-tornado?¶
Long story short, at least for websocket transport:
- On CPython it is (or was) comparable to sockjs-node and socket.io (node.js server)
- On PyPy 1.7 it was 3x faster than sockjs-node and socket.io
You can find more information here.
Can I use query string parameters or cookies to pass data to the server?¶
No, you can not. SockJS does not support application cookies and you can’t pass query string parameters.
How do I implement authentication in my application?¶
Send packet with authentication token after connecting to the server. In pseudo code it can look like this:
Client side:
<script language="javascript">
var sock = new SockJS('/echo');
// Lets assume we invented simple protocol, where first word is a command name and second is a payload.
sock.onconnect = function() {
sock.send('auth,xxx');
sock.send('echo,bar');
};
</script>
Server side:
class EchoConnection(SockJSConnection):
def on_open(self, info):
self.authenticated = False
def on_message(self, msg):
pack, data = msg.split(',', 1)
# Ignore all packets except of 'auth' if user is not yet authenticated
if not self.authenticated and pack != 'auth':
return
if pack == 'auth':
# Decrypt user_id (or user name - you decide). You might want to add salt to the token as well.
user_id = des_decrypt(data, secret_key)
# Validate user_id here by making DB call, etc.
user = get_user(user_id)
if user is None and user.is_active:
self.send('error,Invalid user!')
return
self.authenticated = True
elif pack == 'echo':
self.send(data)
Can I open more than one SockJS connection on same page?¶
No, you can not because of the AJAX restrictions. You have to use connection multiplexing. Check multiplex sample to find out how you can do it.
Can I send python objects through the SockJS?¶
As SockJS emulates websocket protocol and websocket protocol only supports strings, you can not send arbitrary objects (they won’t be JSON serialized automatically). On a side node - SockJS client already includes JSON2.js library, so you can use it without any extra dependencies.
How do I scale sockjs-tornado?¶
Easiest way is to start multiple instances of the sockjs-tornado server (one per core) and load balance them using haproxy. You can find sample haproxy configuration here.
Alternatively, if you already use some kind of load balancer, make sure you enable sticky sessions. sockjs-tornado maintains state for each user and there’s no way to synchronize this state between sockjs-tornado instances.
Also, it is up for you, as a developer, to decide how you’re going to synchronize state of the servers in a cluster. You can use Redis as a meeting point or use ZeroMQ, etc.
API¶
sockjs.tornado.conn¶
sockjs.tornado.conn¶
SockJS connection interface
Callbacks¶
- SockJSConnection.on_open(request)[source]¶
Default on_open() handler.
Override when you need to do some initialization or request validation. If you return False, connection will be rejected.
You can also throw Tornado HTTPError to close connection.
- request
- ConnectionInfo object which contains caller IP address, query string parameters and cookies associated with this request (if any).
Output¶
- SockJSConnection.send(message, binary=False)[source]¶
Send message to the client.
- message
- Message to send.
- SockJSConnection.broadcast(clients, message)[source]¶
Broadcast message to the one or more clients. Use this method if you want to send same message to lots of clients, as it contains several optimizations and will work fast than just having loop in your code.
- clients
- Clients iterable
- message
- Message to send.
sockjs.tornado.router¶
sockjs.tornado.router¶
SockJS protocol router implementation.
- class sockjs.tornado.router.SockJSRouter(connection, prefix='', user_settings={}, io_loop=None)[source]¶
SockJS protocol router
- SockJSRouter.__init__(connection, prefix='', user_settings={}, io_loop=None)[source]¶
Constructor.
- connection
- SockJSConnection class
- prefix
- Connection prefix
- user_settings
- Settings dictionary
- io_loop
- Optional IOLoop instance
URLs¶
sockjs.tornado.session¶
sockjs.tornado.session¶
SockJS session implementation.
Base Session¶
- BaseSession.set_handler(handler)[source]¶
Set transport handler handler
Handler, should derive from the sockjs.tornado.transports.base.BaseTransportMixin.
- BaseSession.send_message(msg, stats=True, binary=False)[source]¶
Send or queue outgoing message
- msg
- Message to send
- stats
- If set to True, will update statistics after operation completes
Connection Session¶
- class sockjs.tornado.session.Session(conn, server, session_id, expiry=None)[source]¶
SockJS session implementation.
- Session.set_handler(handler, start_heartbeat=True)[source]¶
Set active handler for the session
- handler
- Associate active Tornado handler with the session
- start_heartbeat
- Should session start heartbeat immediately
- Session.send_message(msg, stats=True, binary=False)[source]¶
Send or queue outgoing message
- msg
- Message to send
- stats
- If set to True, will update statistics after operation completes
Utilities¶
- class sockjs.tornado.session.ConnectionInfo(ip, cookies, arguments, headers, path)[source]¶
Connection information object.
Will be passed to the on_open handler of your connection class.
Has few properties:
- ip
- Caller IP address
- cookies
- Collection of cookies
- arguments
- Collection of the query string arguments
- headers
- Collection of explicitly exposed headers from the request including: origin, referer, x-forward-for (and associated headers)
- path
- Request uri path
sockjs.tornado.migrate¶
sockjs.tornado.migrate¶
tornado.websocket to sockjs.tornado migration helper.
- class sockjs.tornado.migrate.WebsocketHandler(session)[source]¶
If you already use Tornado websockets for your application and want try sockjs-tornado, change your handlers to derive from this WebsocketHandler class. There are some limitations, for example only self.request only contains remote_ip, cookies and arguments collection
sockjs.tornado.basehandler¶
sockjs.tornado.periodic¶
sockjs.tornado.periodic¶
This module implements customized PeriodicCallback from tornado with support of the sliding window.
- class sockjs.tornado.periodic.Callback(callback, callback_time, io_loop)[source]¶
Custom implementation of the Tornado.Callback with support of callback timeout delays.
sockjs.tornado.sessioncontainer¶
sockjs.tornado.sessioncontainer¶
Simple heapq-based session implementation with sliding expiration window support.
- class sockjs.tornado.sessioncontainer.SessionMixin(session_id=None, expiry=None)[source]¶
Represents one session object stored in the session container. Derive from this object to store additional data.
- __init__(session_id=None, expiry=None)[source]¶
Constructor.
- session_id
- Optional session id. If not provided, will generate new session id.
- expiry
- Expiration time. If not provided, will never expire.
- class sockjs.tornado.sessioncontainer.SessionContainer[source]¶
Session container object.
If we will implement sessions with Tornado timeouts, for polling transports it will be nightmare - if load will be high, number of discarded timeouts will be huge and will be huge performance hit, as Tornado will have to clean them up all the time.
sockjs.tornado.static¶
sockjs.tornado.static¶
Various static handlers required for SockJS to function properly.
- class sockjs.tornado.static.IFrameHandler(application, request, **kwargs)[source]¶
SockJS IFrame page handler
- class sockjs.tornado.static.GreetingsHandler(application, request, **kwargs)[source]¶
SockJS greetings page handler
sockjs.tornado.stats¶
sockjs.tornado.transports.base¶
sockjs.tornado.transports.pollingbase¶
sockjs.tornado.transports.pollingbase¶
Polling transports base
sockjs.tornado.transports.streamingbase¶
- class sockjs.tornado.transports.streamingbase.StreamingTransportBase(application, request, **kwargs)[source]¶
- should_finish()[source]¶
Check if transport should close long running connection after sending X bytes to the client.
- data_len
- Amount of data that was sent
- session_closed()¶
Called by the session when it was closed
sockjs.tornado.transports.xhr¶
sockjs.tornado.transports.xhr¶
Xhr-Polling transport implementation
sockjs.tornado.transports.xhrstreaming¶
sockjs.tornado.transports.xhrstreaming¶
Xhr-Streaming transport implementation
sockjs.tornado.transports.eventsource¶
sockjs.tornado.transports.eventsource¶
EventSource transport implementation.
sockjs.tornado.transports.jsonp¶
sockjs.tornado.transports.jsonp¶
JSONP transport implementation.
sockjs.tornado.transports.htmlfile¶
sockjs.tornado.transports.htmlfile¶
HtmlFile transport implementation.
sockjs.tornado.transports.rawwebsocket¶
sockjs.tornado.transports.rawwebsocket¶
Raw websocket transport implementation