server Package

cherrypyserver Module

WebSocket within CherryPy is a tricky bit since CherryPy is a threaded server which would choke quickly if each thread of the server were kept attached to a long living connection that WebSocket expects.

In order to work around this constraint, we take some advantage of some internals of CherryPy as well as the introspection Python provides.

Basically, when the WebSocket handshake is complete, we take over the socket and let CherryPy take back the thread that was associated with the upgrade request.

These operations require a bit of work at various levels of the CherryPy framework but this module takes care of them and from your application’s perspective, this is abstracted.

Here are the various utilities provided by this module:

  • WebSocketTool: The tool is in charge to perform the

    HTTP upgrade and detach the socket from CherryPy. It runs at various hook points of the request’s processing. Enable that tool at any path you wish to handle as a WebSocket handler.

  • WebSocketPlugin: The plugin tracks the instanciated web socket handlers.

    It also cleans out websocket handler which connection have been closed down. The websocket connection then runs in its own thread that this plugin manages.

Simple usage example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import cherrypy
from ws4py.server.cherrypyserver import WebSocketPlugin, WebSocketTool
from ws4py.websocket import EchoWebSocket

cherrypy.config.update({'server.socket_port': 9000})
WebSocketPlugin(cherrypy.engine).subscribe()
cherrypy.tools.websocket = WebSocketTool()

class Root(object):
    @cherrypy.expose
    def index(self):
        return 'some HTML with a websocket javascript connection'

    @cherrypy.expose
    def ws(self):
        pass
    
cherrypy.quickstart(Root(), '/', config={'/ws': {'tools.websocket.on': True,
                                                 'tools.websocket.handler_cls': EchoWebSocket}})

Note that you can set the handler class on per-path basis, meaning you could also dynamically change the class based on other envrionmental settings (is the user authenticated for ex).

class ws4py.server.cherrypyserver.WebSocketTool[source]

Bases: cherrypy._cptools.Tool

cleanup_headers()[source]

Some clients aren’t that smart when it comes to headers lookup.

complete()[source]

Sets some internal flags of CherryPy so that it doesn’t close the socket down.

start_handler()[source]

Runs at the end of the request processing by calling the opened method of the handler.

upgrade(protocols=None, extensions=None, version=(8, 13), handler_cls=<class 'ws4py.websocket.WebSocket'>)[source]

Performs the upgrade of the connection to the WebSocket protocol.

The provided protocols may be a list of WebSocket protocols supported by the instance of the tool.

When no list is provided and no protocol is either during the upgrade, then the protocol parameter is not taken into account. On the other hand, if the protocol from the handshake isn’t part of the provided list, the upgrade fails immediatly.

class ws4py.server.cherrypyserver.WebSocketPlugin(bus)[source]

Bases: cherrypy.process.plugins.SimplePlugin

broadcast(message, binary=False)[source]

Broadcasts a message to all connected clients known to the server.

Parameters:
  • message – a message suitable to pass to the send() method of the connected handler.
  • binary – whether or not the message is a binary one
cleanup()[source]

Terminate all connections and clear the pool. Executed when the engine stops.

handle(ws_handler, peer_addr)[source]

Tracks the provided handler.

Parameters:
  • ws_handler – websocket handler instance
  • peer_addr – remote peer address for tracing purpose
monitor()[source]

Called within the engine’s mainloop to drop connections that have terminated since last iteration.

start()[source]
stop()[source]

geventserver Module

class ws4py.server.geventserver.UpgradableWSGIHandler(socket, address, server, rfile=None)[source]

Bases: gevent.pywsgi.WSGIHandler

Upgradable version of gevent.pywsgi.WSGIHandler class

This is a drop-in replacement for gevent.pywsgi.WSGIHandler that supports protocol upgrades via WSGI environment. This means you can create upgraders as WSGI apps or WSGI middleware.

If an HTTP request comes in that includes the Upgrade header, it will add to the environment two items:

upgrade.protocol
The protocol to upgrade to. Checking for this lets you know the request wants to be upgraded and the WSGI server supports this interface.
upgrade.socket
The raw Python socket object for the connection. From this you can do any upgrade negotiation and hand it off to the proper protocol handler.

The upgrade must be signalled by starting a response using the 101 status code. This will inform the server to flush the headers and response status immediately, not to expect the normal WSGI app return value, and not to look for more HTTP requests on this connection.

To use this handler with gevent.pywsgi.WSGIServer, you can pass it to the constructor:

1
2
server = WSGIServer(('127.0.0.1', 80), app, 
                    handler_class=UpgradableWSGIHandler)

Alternatively, you can specify it as a class variable for a WSGIServer subclass:

1
2
class UpgradableWSGIServer(gevent.pywsgi.WSGIServer):
      handler_class = UpgradableWSGIHandler
run_application()[source]
class ws4py.server.geventserver.WebSocketServer(address, *args, **kwargs)[source]

Bases: gevent.pywsgi.WSGIServer

handler_class

alias of UpgradableWSGIHandler

handler(websocket)[source]

Table Of Contents

Previous topic

client Package

Next topic

wsgi Package

This Page