mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
fixes gevent websocket example . close #343
This commit is contained in:
parent
90e698aa3c
commit
7a32616407
@ -10,6 +10,7 @@ import struct
|
|||||||
import logging
|
import logging
|
||||||
from socket import error as SocketError
|
from socket import error as SocketError
|
||||||
|
|
||||||
|
import gevent
|
||||||
from gunicorn.workers.async import ALREADY_HANDLED
|
from gunicorn.workers.async import ALREADY_HANDLED
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -85,8 +86,8 @@ class WebSocketWSGI(object):
|
|||||||
"Sec-WebSocket-Version: %s\r\n"
|
"Sec-WebSocket-Version: %s\r\n"
|
||||||
"Sec-WebSocket-Accept: %s\r\n\r\n"
|
"Sec-WebSocket-Accept: %s\r\n\r\n"
|
||||||
% (
|
% (
|
||||||
environ.get('HTTP_ORIGIN'),
|
environ.get('HTTP_ORIGIN'),
|
||||||
environ.get('HTTP_HOST'),
|
environ.get('HTTP_HOST'),
|
||||||
ws.path,
|
ws.path,
|
||||||
version,
|
version,
|
||||||
base64.b64encode(sha1(key + WS_KEY).digest())
|
base64.b64encode(sha1(key + WS_KEY).digest())
|
||||||
@ -97,8 +98,8 @@ class WebSocketWSGI(object):
|
|||||||
handshake_reply += (
|
handshake_reply += (
|
||||||
"WebSocket-Origin: %s\r\n"
|
"WebSocket-Origin: %s\r\n"
|
||||||
"WebSocket-Location: ws://%s%s\r\n\r\n" % (
|
"WebSocket-Location: ws://%s%s\r\n\r\n" % (
|
||||||
environ.get('HTTP_ORIGIN'),
|
environ.get('HTTP_ORIGIN'),
|
||||||
environ.get('HTTP_HOST'),
|
environ.get('HTTP_HOST'),
|
||||||
ws.path))
|
ws.path))
|
||||||
|
|
||||||
sock.sendall(handshake_reply)
|
sock.sendall(handshake_reply)
|
||||||
@ -192,7 +193,7 @@ class WebSocket(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
f = {'fin' : 0,
|
f = {'fin' : 0,
|
||||||
'opcode' : 0,
|
'opcode' : 0,
|
||||||
'mask' : 0,
|
'mask' : 0,
|
||||||
'hlen' : 2,
|
'hlen' : 2,
|
||||||
'length' : 0,
|
'length' : 0,
|
||||||
@ -341,10 +342,10 @@ class WebSocket(object):
|
|||||||
raise ValueError("Don't understand how to parse this type of message: %r" % buf)
|
raise ValueError("Don't understand how to parse this type of message: %r" % buf)
|
||||||
self._buf = buf
|
self._buf = buf
|
||||||
return msgs
|
return msgs
|
||||||
|
|
||||||
def send(self, message):
|
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
|
*message* should be convertable to a string; unicode objects should be
|
||||||
encodable as utf-8. Raises socket.error with errno of 32
|
encodable as utf-8. Raises socket.error with errno of 32
|
||||||
(broken pipe) if the socket has already been closed by the client."""
|
(broken pipe) if the socket has already been closed by the client."""
|
||||||
@ -362,8 +363,8 @@ class WebSocket(object):
|
|||||||
#self._sendlock.release()
|
#self._sendlock.release()
|
||||||
|
|
||||||
def wait(self):
|
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
|
Returns a single message; the oldest not yet processed. If the client
|
||||||
has already closed the connection, returns None. This is different
|
has already closed the connection, returns None. This is different
|
||||||
from normal socket behavior because the empty string is a valid
|
from normal socket behavior because the empty string is a valid
|
||||||
@ -408,3 +409,37 @@ class WebSocket(object):
|
|||||||
self._send_closing_frame()
|
self._send_closing_frame()
|
||||||
self.socket.shutdown(True)
|
self.socket.shutdown(True)
|
||||||
self.socket.close()
|
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)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user