Twisted Python networking library

How to implement Websocket server using Twisted.

HTTP is a request-response type one way protocol. For the web application where continuous data is to be send, websocket was introduced. Unlike HTTP, websocket provides full duplex communication. Websocket, which can be said as an upgraded version of HTTP, is standardized to be used over TCP like HTTP. In this article I will share my experience in implementing websocket with twisted, a framework of python for internet. If you are familiar with websocket, then you can skip to twisted.web or else below is a little introduction to websocket.

WebSocket

To initiate communication using websocket, a Handshake need to be done between client and server. This procedure is backward compatible to HTTP’s request – response structure. First the client sends a handshake request to the server which looks like:

Sending Upgrade header in request with value websocket will acknowledge server about websocket communication. Now if server supports websocket with specified sub-protocols (Sec-WebSocket-Protocol) and version (Sec-WebSocket-Version), it will send adequate response . Possible response could be:

In response, server will send 101 Switching Protocols code and Sec-WebSocket-Accept whose value is calculated using Sec-WebSocket-Key. you can find more information here. After a successful handshake, any of the peer can send data to each other which must be encoded in binary format described in websocket RFC. A high-level overview of the framing is given in the following figure.

Twisted.web

websocket using twisted wire diagramAs in normal twisted.web server , at TCP level, we have HTTPChannel class (a child class of T.I.protocol.Protocol) and server.Site class (which is the child class of T.I.protocol.ServerFactory). Also a Resource instance needs to be passed to server.site class, so that it can serve GET request.

Whenever a data is received, DataReceived method of HTTPChannel is invoked. Now if data starts with ‘GET’, allow the HTTPChannel handle it, which will invoke the render function of the root resource provided to Site class. Render will set 101 response code and will compute the websocket response key. During handshake do not send any raw data, because if handshake is successful this will be considered as framed binary data. Even if you want to send, frame it and send.

If data doesn’t start with ‘GET’, that means we can assume it is a binary encoded message. Now this message can be decoded using Frame.py, which is a very simple data framing module following WebSocket specification. Data send to the client by server should be unmasked as per the websocket specification.

Below is code example of an echo websocket server.

 


Leave a Reply

Your email address will not be published. Required fields are marked *