WebSocket server written in python
Python JavaScript
Switch branches/tags
Nothing to show
Clone or download
Latest commit a83208d Jul 20, 2012
Failed to load latest commit information.
ServiceRoot Removed the debug message for sending stuff to sockets Jun 22, 2012
html Fixed some styling Jun 26, 2012
.gitignore Changed server config file to default.server.config and made git igno… Jul 20, 2012
LICENSE Added license agreements Jun 22, 2012
Processes.py Streamlined the service model a bit by removing the separate clientCo… Jun 19, 2012
Services.py Added silent observer capability and modified the demo to use that to… Jun 20, 2012
WebSocketServer.py Changed -h option to display a help message rather than change the ho… Jun 20, 2012
WebSockets.py Fixed critical bug in which invalid data from a web socket would caus… Jul 20, 2012
default.server.config Changed server config file to default.server.config and made git igno… Jul 20, 2012


Written for Python 2.7

Released under the LGPL

Kevin Cuzner

This is a server meant to run dedicated on a specific port on the host machine.
It provides a method to host multiple WebSocket-based services sorted by
directory and provide a (relatively) easy interface for writing additional
services. This server utilizes multiprocessing for individual services and
threading for handling the client socket operations.

Example of operation:
 - WebSocketServer running on port 12345 of the host machine
 - User requests ws://localhost:12345/foo/bar/
 	- WebSocketServer processes the directory and begins looking in its
 	  service tree for a process named foo->bar->ws_service.py. If the service
 	  isn't found, it looks in the physical directory and attempts to include
 	  the ws_service.py file in that directory. If it cannot, a 404 is issued.
 	  Additionally, if file doesn't contain a class Service, a 500 is issued. If
 	  the service is found and started, the WebSocketServer performs a handshake
 	  and passes the incoming socket off to the Service class
 - User requests ws://localhost:12345/foo/bar
 	- Same as above except the server will look for foo->bar.py to find the
 	  Service class 

A service must implement the Services.Service class which is in the form of a
multiprocessing.Process. The class must be named Service. The main method for
the service should reside in the run() method. Services are imported to run as
though they were in the root directory of the server. Services are provided two
multiprocessing.Queues by the WebSocketServer: sendQueue and recvQueue. These
queues function as pipes for socket information going to and from the service
in the form of WebSockets.WebSocketTransactions. Services should continuously
monitor the recvQueue to determine when to add a new client object and when to
send data to a client object based on the socketId of the transaction object.
The socketId is a unique identifier which is used to map to the actual
WebSocketClient object. WebSocketClients are back-linked to the process id of
the service process that the client is connected to. Whenever something from the
client is sent to the server, a separate thread (a WebSocketManager class) will
negotiate receiving the data into a transaction and sending it off to the
appropriate service's recvQueue. On the service side of things, sending data to
sockets is accomplished by adding a WebSockets.WebSocketTransaction object to
the service sendQueue with a socketId matching the socket id of the client that
was originally sent to the server.

Communication to WebSockets is an event based model with an event being fired
when something happens on the client and the data being available in its
received queue. Using a multithreaded approach for handling individual clients
in each Service is discouraged because of the ease of quickly overwhelming the
server resources (imagine 10,000 long lived sockets on a single processes each
with its own thread...lots of resources). WebSockets are managed as a group
in a separate thread in the main server process to eliminate this problem.
Services do not have direct access to the socket object itself due to
complications in transferring sockets between processes. Instead, queues are
used to communicate with the socket indirectly. An added benefit of this is that
the actual WebSockets protocol is handled by the WebSocket managing thread. To
send data to a socket, a WebSocketClient.Transaction object should be pushed
into the sendQueue of the client. Conversely, received transaction objects will
be made available in the recvQueue.

Services may implement any model for managing the clients which are connected to
the service. A suggestion (which may not be the best for all services) is to
create a class which takes in the socket id that is passed to the service when
the client connects and keep track of this client object throughout its life
(until it receives a close transaction). Then, the service can listen to its
recvQueue and send off the transactions to these "local" classes which would
have a method for handling the reception of a transaction.

The server also provides some limited base classes which can be used to create
an event driven model for a service by way of "subscriptions". This system was
inspired at least partially by the subscription system used in knockoutjs to
create "update" events for normal objects. Services.Subscribable can be
inherited by any class wishing to use the subscription system. Documentation on
the exact usage of this can be found the Subscribable class itself.