#-----------------------------------------------------------------------------# Copyright (c) 2012 - 2022, Anaconda, Inc., and Bokeh Contributors.# All rights reserved.## The full license is in the file LICENSE.txt, distributed with this software.#-----------------------------------------------------------------------------''' Provide a low-level wrapper for Tornado Websockets that adds lockingand smooths some compatibility issues.'''#-----------------------------------------------------------------------------# Boilerplate#-----------------------------------------------------------------------------from__future__importannotationsimportlogging# isort:skiplog=logging.getLogger(__name__)#-----------------------------------------------------------------------------# Imports#-----------------------------------------------------------------------------# Standard library importsfromtypingimportAny,Awaitable,Callable# External importsfromtornadoimportlocksfromtornado.websocketimportWebSocketClientConnection#-----------------------------------------------------------------------------# Globals and constants#-----------------------------------------------------------------------------__all__=('WebSocketClientConnectionWrapper',)#-----------------------------------------------------------------------------# General API#-----------------------------------------------------------------------------#-----------------------------------------------------------------------------# Dev API#-----------------------------------------------------------------------------
[docs]classWebSocketClientConnectionWrapper:''' Used for compatibility across Tornado versions and to add write_lock'''def__init__(self,socket:WebSocketClientConnection)->None:self._socket=socket# write_lock allows us to lock the connection to send multiple# messages atomically.self.write_lock=locks.Lock()# Internal methods --------------------------------------------------------
[docs]asyncdefwrite_message(self,message:str|bytes,binary:bool=False,locked:bool=True)->None:''' Write a message to the websocket after obtaining the appropriate Bokeh Document lock. '''iflocked:withawaitself.write_lock.acquire():self._socket.write_message(message,binary)else:self._socket.write_message(message,binary)
[docs]defclose(self,code:int|None=None,reason:str|None=None)->None:''' Close the websocket. '''returnself._socket.close(code,reason)
[docs]defread_message(self,callback:Callable[...,Any]|None=None)->Awaitable[None|str|bytes]:''' Read a message from websocket and execute a callback. '''returnself._socket.read_message(callback)