2727
2828logger = logging .getLogger ('ws4py' )
2929
30- __all__ = ['WebSocketWSGIHandler' , 'WSGIServer' ]
30+ __all__ = ['WebSocketWSGIHandler' , 'WSGIServer' ,
31+ 'GEventWebSocketPool' ]
3132
3233class WebSocketWSGIHandler (WSGIHandler ):
3334 """
@@ -56,10 +57,35 @@ def run_application(self):
5657
5758 ws = self .environ .pop ('ws4py.websocket' )
5859 if ws :
59- self .server .link_websocket_to_server (ws )
60+ self .server .pool . track (ws )
6061 else :
6162 gevent .pywsgi .WSGIHandler .run_application (self )
6263
64+ class GEventWebSocketPool (Group ):
65+ """
66+ Simple pool of bound websockets.
67+ Internally it uses a gevent group to track
68+ the websockets. The server should call the ``clear``
69+ method to initiate the closing handshake when the
70+ server is shutdown.
71+ """
72+
73+ def track (self , websocket ):
74+ logger .info ("Managing websocket %s" % format_addresses (websocket ))
75+ return self .spawn (websocket .run )
76+
77+ def clear (self ):
78+ logger .info ("Terminating server and all connected websockets" )
79+ for greenlet in self :
80+ try :
81+ websocket = greenlet ._run .im_self
82+ if websocket :
83+ websocket .close (1001 , 'Server is shutting down' )
84+ except :
85+ pass
86+ finally :
87+ self .discard (greenlet )
88+
6389class WSGIServer (_WSGIServer ):
6490 handler_class = WebSocketWSGIHandler
6591
@@ -74,24 +100,15 @@ def __init__(self, *args, **kwargs):
74100 base.
75101 """
76102 _WSGIServer .__init__ (self , * args , ** kwargs )
77- self ._websockets = Group ()
78-
79- def link_websocket_to_server (self , websocket ):
80- logger .info ("Managing websocket %s" % format_addresses (websocket ))
81- self ._websockets .spawn (websocket .run )
103+ self .pool = GEventWebSocketPool ()
82104
83105 def stop (self , * args , ** kwargs ):
84- logger .info ("Terminating server and all connected websockets" )
85- for greenlet in self ._websockets :
86- try :
87- websocket = greenlet ._run .im_self
88- if websocket :
89- websocket .close (1001 , 'Server is shutting down' )
90- except :
91- pass
106+ self .pool .clear ()
92107 _WSGIServer .stop (self , * args , ** kwargs )
93108
94109if __name__ == '__main__' :
110+ import os
111+
95112 from ws4py import configure_logger
96113 configure_logger ()
97114
0 commit comments