1919from .adaptor import ws as ws_adaptor
2020from .page import make_applications , render_page
2121from .remote_access import start_remote_access_service
22- from .utils import cdn_validation , print_listen_address
22+ from .utils import cdn_validation , print_listen_address , deserialize_binary_event
2323from ..session import ScriptModeSession , register_session_implement_for_target , Session
2424from ..session .base import get_session_info_from_headers
2525from ..utils import get_free_port , wait_host_port , STATIC_PATH , check_webio_js , parse_file_size
@@ -90,7 +90,8 @@ def close(self):
9090 self .context .close ()
9191
9292
93- def _webio_handler (applications = None , cdn = True , reconnect_timeout = 0 , check_origin_func = _is_same_site ): # noqa: C901
93+ def _webio_handler (applications = None , cdn = True , reconnect_timeout = 0 , check_origin_func = _is_same_site ) \
94+ -> tornado .websocket .WebSocketHandler : # noqa: C901
9495 """
9596 :param dict applications: dict of `name -> task function`
9697 :param bool/str cdn: Whether to load front-end static resources from CDN
@@ -312,37 +313,46 @@ def start_server_in_current_thread_session():
312313 thread = threading .current_thread ()
313314
314315 class SingleSessionWSHandler (_webio_handler (cdn = False )):
315- session = None
316- instance = None
316+ session : ScriptModeSession = None
317+ instance : typing . ClassVar = None # type: SingleSessionWSHandler
317318 closed = False
318319
320+ def send_msg_to_client (self , session ):
321+ for msg in session .get_task_commands ():
322+ try :
323+ self .write_message (json .dumps (msg ))
324+ except TypeError as e :
325+ logger .exception ('Data serialization error: %s\n '
326+ 'This may be because you pass the wrong type of parameter to the function'
327+ ' of PyWebIO.\n Data content: %s' , e , msg )
328+
319329 def open (self ):
320- self .main_session = False
321- cls = type (self )
322330 if SingleSessionWSHandler .session is None :
323- self .main_session = True
324331 SingleSessionWSHandler .instance = self
325- self .session_id = 'main'
326- cls ._connections [self .session_id ] = self
327-
328332 session_info = get_session_info_from_headers (self .request .headers )
329333 session_info ['user_ip' ] = self .request .remote_ip
330334 session_info ['request' ] = self .request
331335 session_info ['backend' ] = 'tornado'
332336 session_info ['protocol' ] = 'websocket'
333337 self .session = SingleSessionWSHandler .session = ScriptModeSession (
334338 thread , session_info = session_info ,
335- on_task_command = partial ( self .send_msg_to_client , session_id = self . session_id ) ,
339+ on_task_command = self .send_msg_to_client ,
336340 loop = asyncio .get_event_loop ())
337341 websocket_conn_opened .set ()
338-
339- cls ._webio_sessions [self .session_id ] = self .session
340-
341342 else :
342343 self .close ()
343344
345+ def on_message (self , data ):
346+ if isinstance (data , bytes ):
347+ event = deserialize_binary_event (data )
348+ else :
349+ event = json .loads (data )
350+ if event is None :
351+ return
352+ self .session .send_client_event (event )
353+
344354 def on_close (self ):
345- if SingleSessionWSHandler .session is not None and self . main_session :
355+ if self .session is not None :
346356 self .session .close ()
347357 self .closed = True
348358 logger .debug ('ScriptModeSession closed' )
@@ -360,7 +370,7 @@ async def wait_to_stop_loop(server):
360370 )
361371 await asyncio .sleep (0.5 )
362372
363- if SingleSessionWSHandler .instance .session .need_keep_alive ():
373+ if SingleSessionWSHandler .session and SingleSessionWSHandler .session .need_keep_alive ():
364374 while not SingleSessionWSHandler .instance .closed :
365375 await asyncio .sleep (0.5 )
366376
0 commit comments