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)

This comment has been minimized.


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);            

This comment has been minimized.

Mause commented Aug 28, 2012

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


This comment has been minimized.

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


This comment has been minimized.

baxissimo commented Feb 15, 2013

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


This comment has been minimized.

1tylermitchell commented Aug 12, 2013

Awesome, thanks for sharing!


This comment has been minimized.

ImageAsInput commented Aug 14, 2013

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


This comment has been minimized.

dzava commented Aug 24, 2013

@Applterate Check this for multiple client support.


This comment has been minimized.

Sepero commented Nov 4, 2013

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


This comment has been minimized.

alexwahl commented Nov 22, 2013

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?


This comment has been minimized.

cobainmo commented Dec 13, 2013

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 ?


This comment has been minimized.

AlanBell commented May 1, 2014

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


This comment has been minimized.

fredrikhl commented Aug 26, 2014

You have a typo on line 63:

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

This comment has been minimized.

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


This comment has been minimized.

mbirtwell commented Mar 14, 2015

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.


This comment has been minimized.

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:


This comment has been minimized.

nevinvalsaraj commented Jul 2, 2015

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.


This comment has been minimized.

miloszw commented Jul 8, 2015

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


This comment has been minimized.

crossmax commented Jan 12, 2016

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


This comment has been minimized.

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