summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorRyan Williams <breath@alum.mit.edu>2010-05-06 19:18:11 -0700
committerRyan Williams <breath@alum.mit.edu>2010-05-06 19:18:11 -0700
commit80632c134c0a37fca3db03264ca60ff8157cddb5 (patch)
tree65348c0ffd0160cb2a42729eb2abcf9911b52838 /examples
parent45ea653c85a2f0438d80320d2e80e75dc3283290 (diff)
downloadeventlet-80632c134c0a37fca3db03264ca60ff8157cddb5.tar.gz
Moved WebSocketWSGI class into eventlet.websocket and added a fewtests to bring it back up to 100%. Refactored the example to reference eventlet.websocket.
Diffstat (limited to 'examples')
-rw-r--r--examples/websocket.py117
1 files changed, 7 insertions, 110 deletions
diff --git a/examples/websocket.py b/examples/websocket.py
index 56f6d1e..9bac0e2 100644
--- a/examples/websocket.py
+++ b/examples/websocket.py
@@ -1,109 +1,6 @@
-import collections
-import errno
import eventlet
from eventlet import wsgi
-from eventlet import pools
-from eventlet.support import get_errno
-
-class WebSocketWSGI(object):
- def __init__(self, handler, origin):
- self.handler = handler
- self.origin = origin
-
- def verify_client(self, ws):
- pass
-
- def __call__(self, environ, start_response):
- if not (environ['HTTP_CONNECTION'] == 'Upgrade' and
- environ['HTTP_UPGRADE'] == 'WebSocket'):
- # need to check a few more things here for true compliance
- start_response('400 Bad Request', [('Connection','close')])
- return []
-
- sock = environ['eventlet.input'].get_socket()
- ws = WebSocket(sock,
- environ.get('HTTP_ORIGIN'),
- environ.get('HTTP_WEBSOCKET_PROTOCOL'),
- environ.get('PATH_INFO'))
- self.verify_client(ws)
- handshake_reply = ("HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
- "Upgrade: WebSocket\r\n"
- "Connection: Upgrade\r\n"
- "WebSocket-Origin: %s\r\n"
- "WebSocket-Location: ws://%s%s\r\n\r\n" % (
- self.origin,
- environ.get('HTTP_HOST'),
- ws.path))
- sock.sendall(handshake_reply)
- try:
- self.handler(ws)
- except socket.error, e:
- if get_errno(e) != errno.EPIPE:
- raise
- # use this undocumented feature of eventlet.wsgi to ensure that it
- # doesn't barf on the fact that we didn't call start_response
- return wsgi.ALREADY_HANDLED
-
-def parse_messages(buf):
- """ Parses for messages in the buffer *buf*. It is assumed that
- the buffer contains the start character for a message, but that it
- may contain only part of the rest of the message. NOTE: only understands
- lengthless messages for now.
-
- Returns an array of messages, and the buffer remainder that didn't contain
- any full messages."""
- msgs = []
- end_idx = 0
- while buf:
- assert ord(buf[0]) == 0, "Don't understand how to parse this type of message: %r" % buf
- end_idx = buf.find("\xFF")
- if end_idx == -1:
- break
- msgs.append(buf[1:end_idx].decode('utf-8', 'replace'))
- buf = buf[end_idx+1:]
- return msgs, buf
-
-def format_message(message):
- # TODO support iterable messages
- if isinstance(message, unicode):
- message = message.encode('utf-8')
- elif not isinstance(message, str):
- message = str(message)
- packed = "\x00%s\xFF" % message
- return packed
-
-
-class WebSocket(object):
- def __init__(self, sock, origin, protocol, path):
- self.sock = sock
- self.origin = origin
- self.protocol = protocol
- self.path = path
- self._buf = ""
- self._msgs = collections.deque()
- self._sendlock = pools.TokenPool(1)
-
- def send(self, message):
- packed = format_message(message)
- # if two greenthreads are trying to send at the same time
- # on the same socket, sendlock prevents interleaving and corruption
- t = self._sendlock.get()
- try:
- self.sock.sendall(packed)
- finally:
- self._sendlock.put(t)
-
- def wait(self):
- while not self._msgs:
- # no parsed messages, must mean buf needs more data
- delta = self.sock.recv(1024)
- if delta == '':
- return None
- self._buf += delta
- msgs, self._buf = parse_messages(self._buf)
- self._msgs.extend(msgs)
- return self._msgs.popleft()
-
+from eventlet import websocket
# demo app
import os
@@ -122,21 +19,21 @@ def handle(ws):
for i in xrange(10000):
ws.send("0 %s %s\n" % (i, random.random()))
eventlet.sleep(0.1)
-
-wsapp = WebSocketWSGI(handle, 'http://localhost:7000')
+
+wsapp = websocket.WebSocketWSGI(handle)
def dispatch(environ, start_response):
""" This resolves to the web page or the websocket depending on
the path."""
- if environ['PATH_INFO'] == '/':
+ if environ['PATH_INFO'] == '/data':
+ return wsapp(environ, start_response)
+ else:
start_response('200 OK', [('content-type', 'text/html')])
return [open(os.path.join(
os.path.dirname(__file__),
'websocket.html')).read()]
- else:
- return wsapp(environ, start_response)
-
if __name__ == "__main__":
# run an example app from the command line
listener = eventlet.listen(('localhost', 7000))
+ print "\nVisit http://localhost:7000/ in your websocket-capable browser.\n"
wsgi.server(listener, dispatch)