[Web-SIG] websocket support in WSGI

Marcel Hellkamp marc at gsites.de
Mon May 21 23:48:42 CEST 2012


Am 21.05.2012 15:47, schrieb Simon Sapin:
> Le 21/05/2012 14:36, Alex Grönholm a écrit :
>> This has been discussed before and it's impossible to implement since
>> proxying such things does not work over a number of protocols (FCGI,
>> SCGI). IIRC, the front-end web server likes to send its own 1xx response
>> before the application has a chance to send its own. The original
>> discussion was about implement WebDAV, but WebSocket has the same issues.
> 
> What would be possible is a server that does HTTP + WebSocket on the
> network side and WSGI + (some other API for WebSocket) on the
> application side, although I don’t know a server doing this.
> 

gevent and the gevent-websocket does this.
http://bottlepy.org/docs/dev/async.html#finally-websockets

The idea: A modified gevent server detects WebSocket requests and
immediately answers with handshake headers. Then it puts a socket-like
object in environ['wsgi.websocket'] and calls the WSGI application with
a dummy start_response() callable.

In this mode, the start_response() does nothing and the body iterator is
ignored. As long as the application callable blocks (or the body
iterator yields something), the socket stays open.

Problems with this API: The application is required to block, thus
blocking the handling server thread. Traditional threading servers have
limited thread-pools. Non-blocking servers (twisted/tornado) would
freeze completely.




I thought about a similar API a while ago, but with some important
changes. The server would put a callable in environ['wsgi.detach'] that,
when called, returns a socket-like object and changes the behavior of
the server as follows:

1) Calling start_response() after wsgi.detach() writes the headers to
the socket immediately (instead of buffering them). Calling it again is
an error. Not calling it is allowed, though.
2) The socket is not closed after the body iterator is exhausted. The
client has to close it explicitly.

In other words: The responsibility for the connection (and socket) is
passed to the application.

This works well with traditional threaded servers. The application can
spawn a new worker thread, put the job into a queue or whatever and then
return from the application callable, allowing the server thread to
continue handling new connections. Same goes for non-blocking servers.
And best of all: This API would be fully optional and backwards
compatible to WSGI.

Thoughts?


More information about the Web-SIG mailing list