SHARE
TWEET

Python WebSocket Server

gauravmm Mar 30th, 2011 982 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import socket
  2. import sys
  3. import threading
  4.  
  5.  
  6. def start():
  7.     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  8.     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  9.     # listen for upto 50 cnxns on port 8000
  10.     sock.bind(('', 8000))
  11.     sock.listen(50)
  12.  
  13.     while True:
  14.         csock,caddr = sock.accept()
  15.         print "Connection from: ", caddr
  16.         # Start a thread to service each cnxn
  17.         t = threading.Thread(target=handle_cnxn, args=(csock,))
  18.         t.start()
  19.  
  20.  
  21. def handle_cnxn(csock):
  22.     shake1 = csock.recv(1024)
  23.    
  24.     shakelist = shake1.split("\r\n")
  25.     # The body follows a \r\n after the 'headers'
  26.     body = shake1.split("\r\n\r\n")[1]
  27.  
  28.     # Extract key1 and key2
  29.     for elem in shakelist:
  30.         if elem.startswith("Sec-WebSocket-Key1:"):
  31.             key1 = elem[20:]  # Sec-WebSocket-Key1: is 20 chars
  32.         elif elem.startswith("Sec-WebSocket-Key2:"):
  33.             key2 = elem[20:]
  34.         elif elem.startswith("Origin:"):
  35.             ws_origin = elem[8:]
  36.         elif elem.startswith("Host:"):
  37.             ws_host = elem[6:]
  38.         elif elem.startswith("GET "):
  39.             ws_path = elem[4:-9]
  40.         else:
  41.             continue
  42.  
  43.     # Count spaces
  44.     nums1 = key1.count(" ")
  45.     nums2 = key2.count(" ")
  46.     # Join digits in the key
  47.     num1 = ''.join([x for x in key1 if x.isdigit()])
  48.     num2 = ''.join([x for x in key2 if x.isdigit()])
  49.    
  50.     # Divide the digits by the num of spaces
  51.     key1 = int(int(num1)/int(nums1))
  52.     key2 = int(int(num2)/int(nums2))
  53.  
  54.     # Pack into Network byte ordered 32 bit ints
  55.     import struct
  56.     key1 = struct.pack("!I", key1)
  57.     key2 = struct.pack("!I", key2)
  58.  
  59.     # Concat key1, key2, and the the body of the client handshake and take the md5 sum of it
  60.     key = key1 + key2 + body
  61.     import hashlib
  62.     m = hashlib.md5()
  63.     m.update(key)
  64.     d = m.digest()
  65.  
  66.     # Send 'headers'
  67.     # Modified to automatically adhere to the Same-Origin Policy.
  68.     #   DO NOT USE IN PRODUCTION CODE!!!
  69.     csock.send("HTTP/1.1 101 WebSocket Protocol Handshake\r\n")
  70.     csock.send("Upgrade: WebSocket\r\n")
  71.     csock.send("Connection: Upgrade\r\n")
  72.     csock.send("Sec-WebSocket-Origin: " + ws_origin + "\r\n")
  73.     csock.send("Sec-WebSocket-Location: ws://" + ws_host + ws_path + "\r\n")
  74.     csock.send("Sec-WebSocket-Protocol: chat\r\n")
  75.     csock.send("\r\n")
  76.     #Send digest
  77.     csock.send(d)
  78.  
  79.     # Message framing - 0x00 utf-8-encoded-body 0xFF
  80.     def send(data):
  81.         first_byte = chr(0x00)
  82.         payload = data.encode('utf-8')
  83.         pl = first_byte + payload + chr(0xFF)
  84.         csock.send(pl)
  85.  
  86.    
  87.     from time import sleep
  88.  
  89.     # This is dependent on you - what you wish to send to the browser
  90.     i = 0
  91.     while True:
  92.         send(u"%s" % (i))
  93.         i += 1
  94.         sleep(1)
  95.  
  96. if __name__ == "__main__":
  97.     start()
RAW Paste Data
Top