ws4py provides an extension to CherryPy 3 to enable WebSocket from the framework layer. It is based on the CherryPy plugin and tool mechanisms.
The :class:`WebSocket tool <ws4py.server.cherrypyserver.WebSocketTool>` plays at the request level on every request received by the server. Its goal is to perform the WebSocket handshake and, if it succeeds, to create the :class:`WebSocket <ws4py.websocket.WebSocket>` instance (well a subclass you will be implementing) and push it to the plugin.
The :class:`WebSocket plugin <ws4py.server.cherrypyserver.WebSocketPlugin>` works at the CherryPy system level and has a single instance throughout. Its goal is to track websocket instances created by the tool and free their resources when connections are closed.
Here is a simple example of an echo server:
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):
# you can access the class instance through
handler = cherrypy.request.ws_handler
cherrypy.quickstart(Root(), '/', config={'/ws': {'tools.websocket.on': True,
'tools.websocket.handler_cls': EchoWebSocket}})Note how we specify the class which should be instanciated by the server on each connection. The great aspect of the tool mechanism is that you can specify a different class on a per-path basis.
gevent is a coroutine, called greenlets, implementation for very concurrent applications. ws4py offers a server implementation for this library on top of the WSGI protocol. Using it is as simple as:
from gevent import monkey; monkey.patch_all()
import gevent
from ws4py.server.geventserver import WebSocketServer
from ws4py.websocket import EchoWebSocket
server = WebSocketServer(('127.0.0.1', 9001), websocket_class=EchoWebSocket)
server.serve_forever()First we patch all the standard modules so that the stdlib runs well with as gevent. Then we simply create a WSGI server and specify the class which will be instanciated internally each time a connection is successful.