2
2
from gevent .event import Event
3
3
from gevent .queue import Queue
4
4
from gevent .select import select
5
+ from gevent .monkey import patch_all ; patch_all ()
5
6
import uuid
6
7
7
8
from . import WebSocket , WebSocketClient , WebSocketMiddleware
8
9
from ._uwsgi import uwsgi
9
10
10
11
11
12
class GeventWebSocketClient (object ):
12
- def __init__ (self , send_event , send_queue , recv_event , recv_queue , timeout = 60 ):
13
+ def __init__ (self , fd , send_event , send_queue , recv_event , recv_queue , timeout = 60 ):
13
14
self .id = str (uuid .uuid1 ())
15
+ self .fd = fd
14
16
self .send_event = send_event
15
17
self .send_queue = send_queue
16
18
self .recv_event = recv_event
@@ -20,12 +22,10 @@ def __init__(self, send_event, send_queue, recv_event, recv_queue, timeout=60):
20
22
def send (self , message ):
21
23
self .send_queue .put (message )
22
24
self .send_event .set ()
23
- self .send_event .clear ()
24
25
25
26
def receive (self ):
26
27
self .recv_event .set ()
27
- self .recv_event .clear ()
28
- self .recv_queue .get ()
28
+ return self .recv_queue .get ()
29
29
30
30
31
31
class GeventWebSocketMiddleware (WebSocketMiddleware ):
@@ -40,37 +40,41 @@ def __call__(self, environ, start_response):
40
40
# do handshake
41
41
uwsgi .websocket_handshake (environ ['HTTP_SEC_WEBSOCKET_KEY' ], environ .get ('HTTP_ORIGIN' , '' ))
42
42
43
+ # setup events
43
44
send_event = Event ()
44
45
send_queue = Queue ()
45
46
46
47
recv_event = Event ()
47
48
recv_queue = Queue ()
48
49
49
- client = self .client (send_event , send_queue , recv_event , recv_queue )
50
+ client = self .client (uwsgi . connection_fd (), send_event , send_queue , recv_event , recv_queue )
50
51
51
- fd = uwsgi .connection_fd ()
52
+ # spawn handler
53
+ spawn (handler , client )
52
54
53
- def send ():
54
- ready .set ()
55
- message = send_queue .get ()
56
- uwsgi .websocket_send (message )
57
- send_event .rawlink (send )
58
-
59
- def listen ():
60
- ready .set ()
61
- select ([fd ], [], [], client .timeout )
62
- try :
63
- recv_queue .put (uwsgi .websocket_recv_nb ())
64
- except IOError : # client disconnected
65
- pass
66
- recv_event .rawlink (listen )
67
-
68
- ready = Event ()
55
+ # spawn recv listener
56
+ def listener (client ):
57
+ ready = select ([client .fd ], [], [], client .timeout )
58
+ recv_event .set ()
59
+ spawn (listener , client )
69
60
70
61
while True :
71
- ready .clear ()
72
- ready .wait ()
73
-
62
+ if send_event .is_set ():
63
+ send_event .clear ()
64
+ try :
65
+ uwsgi .websocket_send (send_queue .get ())
66
+ except IOError : # client disconnected
67
+ pass
68
+
69
+ if recv_event .is_set ():
70
+ recv_event .clear ()
71
+ try :
72
+ recv_queue .put (uwsgi .websocket_recv_nb ())
73
+ spawn (listener , client )
74
+ except IOError : # client disconnected
75
+ pass
76
+
77
+ sleep (0.1 )
74
78
75
79
class GeventWebSocket (WebSocket ):
76
80
middleware = GeventWebSocketMiddleware
0 commit comments