Skip to content

Instantly share code, notes, and snippets.

@geoffb
Created October 7, 2010 23:37
Show Gist options
  • Select an option

  • Save geoffb/616117 to your computer and use it in GitHub Desktop.

Select an option

Save geoffb/616117 to your computer and use it in GitHub Desktop.

Revisions

  1. geoffb created this gist Oct 7, 2010.
    67 changes: 67 additions & 0 deletions simple_websocket_client.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,67 @@
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <title>WebSocket Client</title>
    <style>
    #output {
    border: solid 1px #000;
    }
    </style>
    </head>
    <body>

    <form id="form">
    <input type="text" id="message">
    <button type="submit">Send</button>
    </form>

    <hr>

    <div id="output"></div>

    <script>

    var inputBox = document.getElementById("message");
    var output = document.getElementById("output");
    var form = document.getElementById("form");

    try {

    var host = "ws://" + window.location.hostname + ":9876/stuff";
    console.log("Host:", host);

    var s = new WebSocket(host);

    s.onopen = function (e) {
    console.log("Socket opened.");
    };

    s.onclose = function (e) {
    console.log("Socket closed.");
    };

    s.onmessage = function (e) {
    console.log("Socket message:", e.data);
    var p = document.createElement("p");
    p.innerHTML = e.data;
    output.appendChild(p);
    };

    s.onerror = function (e) {
    console.log("Socket error:", e);
    };

    } catch (ex) {
    console.log("Socket exception:", ex);
    }

    form.addEventListener("submit", function (e) {
    e.preventDefault();
    s.send(inputBox.value);
    inputBox.value = "";
    }, false)

    </script>

    </body>
    </html>
    89 changes: 89 additions & 0 deletions simple_websocket_server.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,89 @@
    #!/usr/bin/env python

    import socket, struct, hashlib, threading, cgi

    def decode_key (key):
    num = ""
    spaces = 0
    for c in key:
    if c.isdigit():
    num += c
    if c.isspace():
    spaces += 1
    return int(num) / spaces

    def create_hash (key1, key2, code):
    a = struct.pack(">L", decode_key(key1))
    b = struct.pack(">L", decode_key(key2))
    md5 = hashlib.md5(a + b + code)
    return md5.digest()

    def recv_data (client, length):
    data = client.recv(length)
    if not data: return data
    return data.decode('utf-8', 'ignore')

    def send_data (client, data):
    message = "\x00%s\xFF" % data.encode('utf-8')
    return client.send(message)

    def parse_headers (data):
    headers = {}
    lines = data.splitlines()
    for l in lines:
    parts = l.split(": ", 1)
    if len(parts) == 2:
    headers[parts[0]] = parts[1]
    headers['code'] = lines[len(lines) - 1]
    return headers

    def handshake (client):
    print 'Handshaking...'
    data = client.recv(1024)
    headers = parse_headers(data)
    print 'Got headers:'
    for k, v in headers.iteritems():
    print k, ':', v
    digest = create_hash(
    headers['Sec-WebSocket-Key1'],
    headers['Sec-WebSocket-Key2'],
    headers['code']
    )
    shake = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
    shake += "Upgrade: WebSocket\r\n"
    shake += "Connection: Upgrade\r\n"
    shake += "Sec-WebSocket-Origin: %s\r\n" % (headers['Origin'])
    shake += "Sec-WebSocket-Location: ws://%s/stuff\r\n" % (headers['Host'])
    shake += "Sec-WebSocket-Protocol: sample\r\n\r\n"
    shake += digest
    return client.send(shake)

    def handle (client, addr):
    handshake(client)
    lock = threading.Lock()
    while 1:
    data = recv_data(client, 1024)
    if not data: break
    data = cgi.escape(data)
    lock.acquire()
    [send_data(c, data) for c in clients]
    lock.release()
    print 'Client closed:', addr
    lock.acquire()
    clients.remove(client)
    lock.release()
    client.close()

    def start_server ():
    s = socket.socket()
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(('', 9876))
    s.listen(5)
    while 1:
    conn, addr = s.accept()
    print 'Connection from:', addr
    clients.append(conn)
    threading.Thread(target = handle, args = (conn, addr)).start()

    clients = []
    start_server()