Skip to content

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)
Copy link

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

Copy link

Mause commented Aug 28, 2012

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

Copy link

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

Copy link

baxissimo commented Feb 15, 2013

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

Copy link

1tylermitchell commented Aug 12, 2013

Awesome, thanks for sharing!

Copy link

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 ?

Copy link

dzava commented Aug 24, 2013

@Applterate Check this for multiple client support.

Copy link

Sepero commented Nov 4, 2013

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

Copy link

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?

Copy link

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 ?

Copy link

AlanBell commented May 1, 2014

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

Copy link

fredrikhl commented Aug 26, 2014

You have a typo on line 63:

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

Copy link

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

Copy link

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.

Copy link

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:

Copy link

nevalsar 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.

Copy link

mwielondek commented Jul 8, 2015

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

Copy link

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

Copy link

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