¿Cómo envío un mensaje websocket en Tornado a voluntad?

Soy muy nuevo en Tornado y quería saber si es posible enviar un mensaje (write_message) a voluntad desde el progtwig Python a todos los clientes. Por ejemplo, digamos que mi progtwig está monitoreando un directorio para ver si un archivo aparece / existe. Cuando aparezca, deseo enviar un mensaje de socket web a un cliente del navegador que el archivo existe. Parece que no entiendo cómo invocar el método “write_message” sin antes recibir un mensaje websocket (controlador on_message).

Incluso si uso el método “PeriodicCallback”, todavía no tengo claro cómo llamo al método “write_message”. ¿Hay ejemplos de cómo invocar “write_message” sin hacerlo dentro del controlador “on_message”?

Debe mantener una colección de websockets abiertos e iterar a través de esa colección a voluntad para enviar mensajes.

Como ejemplo, enviaré un mensaje cada vez que un cliente se conecte a your.domain.example/test/ pero la idea es la misma siempre que quiera enviar algo:

 import os.path import logging from tornado import ioloop, web, websocket SERVER_FOLDER = os.path.abspath(os.path.dirname(__file__)) LOGGER = logging.getLogger('tornado.application') class TestHandler(web.RequestHandler): def get(self): server = ioloop.IOLoop.current() data = "whatever" server.add_callback(DefaultWebSocket.send_message, data) self.set_status(200) self.finish() class DefaultWebSocket(websocket.WebSocketHandler): live_web_sockets = set() def open(self): LOGGER.debug("WebSocket opened") self.set_nodelay(True) self.live_web_sockets.add(self) self.write_message("you've been connected. Congratz.") def on_message(self, message): LOGGER.debug('Message incomming: %s', message) def on_close(self): LOGGER.debug("WebSocket closed") @classmethod def send_message(cls, message): removable = set() for ws in cls.live_web_sockets: if not ws.ws_connection or not ws.ws_connection.stream.socket: removable.add(ws) else: ws.write_message(message) for ws in removable: cls.live_web_sockets.remove(ws) def serve_forever(port=80, address=''): application = web.Application([ (r"/test/", TestHandler), (r"/websocket/", DefaultWebSocket), ... ], static_path=os.path.join(SERVER_FOLDER, ...), debug=True, ) application.listen(port, address) LOGGER.debug( 'Server listening at http://%s:%d/', address or 'localhost', port) ioloop.IOLoop.current().start() if __name__ == "__main__": serve_forever() 

Obviamente, necesitarás crear un websocket en el navegador usando el siguiente JavaScript:

 socket = new WebSocket('ws://your.domain.example:80/websocket/'); 

Y gestionarlo en consecuencia.