Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
A simple WebSockets server with no dependencies
import struct
import SocketServer
from base64 import b64encode
from hashlib import sha1
from mimetools import Message
from StringIO import StringIO
class WebSocketsHandler(SocketServer.StreamRequestHandler):
magic = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
def setup(self):
print "connection established", self.client_address
self.handshake_done = False
def handle(self):
while True:
if not self.handshake_done:
def read_next_message(self):
length = ord([1]) & 127
if length == 126:
length = struct.unpack(">H",[0]
elif length == 127:
length = struct.unpack(">Q",[0]
masks = [ord(byte) for byte in]
decoded = ""
for char in
decoded += chr(ord(char) ^ masks[len(decoded) % 4])
def send_message(self, message):
length = len(message)
if length <= 125:
elif length >= 126 and length <= 65535:
self.request.send(struct.pack(">H", length))
self.request.send(struct.pack(">Q", length))
def handshake(self):
data = self.request.recv(1024).strip()
headers = Message(StringIO(data.split('\r\n', 1)[1]))
if headers.get("Upgrade", None) != "websocket":
print 'Handshaking...'
key = headers['Sec-WebSocket-Key']
digest = b64encode(sha1(key + self.magic).hexdigest().decode('hex'))
response = 'HTTP/1.1 101 Switching Protocols\r\n'
response += 'Upgrade: websocket\r\n'
response += 'Connection: Upgrade\r\n'
response += 'Sec-WebSocket-Accept: %s\r\n\r\n' % digest
self.handshake_done = self.request.send(response)
def on_message(self, message):
print messsage
if __name__ == "__main__":
server = SocketServer.TCPServer(
("localhost", 9999), WebSocketsHandler)

jkp commented Jul 18, 2012

Try it out with something like this ( is handy for quick tests...):

var ws = new WebSocket("ws://localhost:9999/");
ws.onopen = function() {
    function schedule(i) {
        setTimeout(function() { 
          ws.send('Hello from the client! (iteration ' + i + ')');
          schedule(i + 1);
        }, 1000);            

Mause commented Aug 28, 2012

I'm working on something using this as the websocket backend and the Webkit notification API :D


ghost commented Nov 4, 2012

You have a typo in your on_message method; you've got the letter S three times on line 63

def on_message(self, message):
print messsage # typo

You should change the serve_forever() part to something like this:
except KeyboardInterrupt:
print "Got ^C"
print "bye!"

Awesome, thanks for sharing!

I am facing a weird problem. Only one client can be connected to this server. Am I missing something really basic ?

dzava commented Aug 24, 2013

@applterate Check this for multiple client support.

Sepero commented Nov 4, 2013

Very impressive. I am happy to be a witness to the excellence of this code.

im trying to use this with python3.. struggling with mimetools.Message can somebody give me a hint how to replace correct with the email package?

I'm totally noob with python and need to make something fast so pelase can you help me. How can i create instance of this class and use send_message() method from external file ?

AlanBell commented May 1, 2014

self.request.send(126) should be self.request.send(chr(126)), same for 127.

You have a typo on line 63:

  def on_message(self, message):
-     print messsage
+     print message

SevenW commented Sep 25, 2014

Thanks for this nice example, which inspired (as in reuse some code) to make a combined HTTP/WebSocket server using one and the same port. The HTTP server part is based on the standard SimpleHTTPServer library.

and for more background: for some background

Thank you @jkp that was very helpful. I've taken it one step further than @SevenW and turned it in to an git repository ( I've got examples there of getting this to work with SimpleHTTPServer, wsgiref and werkzeug.

SevenW commented May 25, 2015

I have added support for SSL/HTTPS, and added exception handling. I updated my gist,
and also created a repository for further maintenance:

An elaborate example for the web interface for Plugwise-2-py can be found here:

Thanks @jkp, that's lightweight and serves most development purposes. I recommend adding

SocketServer.TCPServer.allow_reuse_address = True

to set SO_REUSEADDR socket option before TCPServer instantiation on line 66 in case the script is run repeatedly during development.

miloszw commented Jul 8, 2015

Here is a somewhat more modular version if anyone wants to use this as an import.

Hi, I trying launch the web socket server with param secure and I get this error:

File "", line 50, in _ws_main
    server.socket = ssl.wrap_socket (server.socket, certfile='./server.pem', server_side=True)
File "/usr/lib/python2.7/", line 891, in wrap_socket
File "/usr/lib/python2.7/", line 509, in __init__
    self._context.load_cert_chain(certfile, keyfile)
ssl.SSLError: [SSL] PEM lib (_ssl.c:2525)

I read that this error is caused for a bad private key, but I've added it as a parameter in the function wrap_socket() and result is the same. My cert and key are self-signed, I created it with openssl command.
How I can resolve this?

Thanks in advance

abs1001 commented Oct 13, 2017

i need to send binary data over this server. will it work ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment