Skip to content

Instantly share code, notes, and snippets.

@luciferous
Created April 27, 2010 07:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luciferous/380454 to your computer and use it in GitHub Desktop.
Save luciferous/380454 to your computer and use it in GitHub Desktop.
WebSocket protocol for Diesel

WebSocket protocol for Diesel

Not tested, but a potential echo + timeout example:

from diesel import Application, Service, until_eol, sleep, bytes
from websocket import WebSocket
import time

def skip_one():
    yield bytes(1)
    yield up(until_eol())

def hi_server():
    while True:
        inp, to = yield (skip_one, sleep(3))
        if to:
            yield '%s timeout!\n' % time.asctime()
        else:
            yield 'you said %s' % inp

app = Application()
app.add_service(Service(WebSocket(hi_server), 8000))
app.run()
'''
Websocket for Diesel.
'''
from diesel import until
BEGINFRAME, ENDFRAME = '\x00', '\xff'
HANDSHAKE = '''\
HTTP/1.1 101 Web Socket Protocol Handshake\r\n\
Upgrade: WebSocket\r\n\
Connection: Upgrade\r\n'''
class WebSocketError(Exception): pass
class Request(object):
'''WebSocket request.
'''
def __init__(self, method, path, version):
self.method, self.path, self.version = method, path, version
def parse_headers(self, headers):
self.headers = dict([
line.split(': ')
for line in headers.split('\r\n')
])
class WebSocket(object):
'''WebSocket service.
'''
def __init__(self, app):
self.app = app()
def __call__(self, addr):
'''WebSocket handler.
'''
yield HANDSHAKE
request_line = yield until('\r\n')
headers = yield until('\r\n\r\n')
req = Request(*request_line.strip().split(' '))
req.parse_headers(headers.strip())
origin = 'WebSocket-Origin: %s' % req.headers['Origin']
loc = 'WebSocket-Location: ws://%s' % req.headers['Host'] + req.path
yield '%s\r\n%s\r\n\r\n' % (origin, loc)
while True:
start, out = yield (bytes(1), self.app.next())
if start:
if not start == BEGINFRAME:
raise WebSocketError()
incoming = yield (until(ENDFRAME))
self.app.send(incoming)
else:
yield out
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment