From 7a32616407c702b0aac4e5e7aff0f6a6e36e9c40 Mon Sep 17 00:00:00 2001 From: benoitc Date: Tue, 15 May 2012 00:13:48 +0200 Subject: [PATCH] fixes gevent websocket example . close #343 --- examples/websocket/gevent_websocket.py | 55 +++++++++++++++++++++----- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/examples/websocket/gevent_websocket.py b/examples/websocket/gevent_websocket.py index 4e7b3483..64b5fb37 100644 --- a/examples/websocket/gevent_websocket.py +++ b/examples/websocket/gevent_websocket.py @@ -10,6 +10,7 @@ import struct import logging from socket import error as SocketError +import gevent from gunicorn.workers.async import ALREADY_HANDLED logger = logging.getLogger(__name__) @@ -85,8 +86,8 @@ class WebSocketWSGI(object): "Sec-WebSocket-Version: %s\r\n" "Sec-WebSocket-Accept: %s\r\n\r\n" % ( - environ.get('HTTP_ORIGIN'), - environ.get('HTTP_HOST'), + environ.get('HTTP_ORIGIN'), + environ.get('HTTP_HOST'), ws.path, version, base64.b64encode(sha1(key + WS_KEY).digest()) @@ -97,8 +98,8 @@ class WebSocketWSGI(object): handshake_reply += ( "WebSocket-Origin: %s\r\n" "WebSocket-Location: ws://%s%s\r\n\r\n" % ( - environ.get('HTTP_ORIGIN'), - environ.get('HTTP_HOST'), + environ.get('HTTP_ORIGIN'), + environ.get('HTTP_HOST'), ws.path)) sock.sendall(handshake_reply) @@ -192,7 +193,7 @@ class WebSocket(object): """ f = {'fin' : 0, - 'opcode' : 0, + 'opcode' : 0, 'mask' : 0, 'hlen' : 2, 'length' : 0, @@ -341,10 +342,10 @@ class WebSocket(object): raise ValueError("Don't understand how to parse this type of message: %r" % buf) self._buf = buf return msgs - + def send(self, message): - """Send a message to the browser. - + """Send a message to the browser. + *message* should be convertable to a string; unicode objects should be encodable as utf-8. Raises socket.error with errno of 32 (broken pipe) if the socket has already been closed by the client.""" @@ -362,8 +363,8 @@ class WebSocket(object): #self._sendlock.release() def wait(self): - """Waits for and deserializes messages. - + """Waits for and deserializes messages. + Returns a single message; the oldest not yet processed. If the client has already closed the connection, returns None. This is different from normal socket behavior because the empty string is a valid @@ -408,3 +409,37 @@ class WebSocket(object): self._send_closing_frame() self.socket.shutdown(True) self.socket.close() + + +# demo app +import os +import random +def handle(ws): + """ This is the websocket handler function. Note that we + can dispatch based on path in here, too.""" + if ws.path == '/echo': + while True: + m = ws.wait() + if m is None: + break + ws.send(m) + + elif ws.path == '/data': + for i in xrange(10000): + ws.send("0 %s %s\n" % (i, random.random())) + gevent.sleep(0.1) + +wsapp = WebSocketWSGI(handle) +def app(environ, start_response): + """ This resolves to the web page or the websocket depending on + the path.""" + if environ['PATH_INFO'] == '/' or environ['PATH_INFO'] == "": + data = open(os.path.join( + os.path.dirname(__file__), + 'websocket.html')).read() + data = data % environ + start_response('200 OK', [('Content-Type', 'text/html'), + ('Content-Length', len(data))]) + return [data] + else: + return wsapp(environ, start_response)