Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在Tornado中随意发送websocket消息?_Python_Websocket_Tornado - Fatal编程技术网

Python 如何在Tornado中随意发送websocket消息?

Python 如何在Tornado中随意发送websocket消息?,python,websocket,tornado,Python,Websocket,Tornado,我是Tornado的新手,我想知道是否可以在Python程序中随意向所有客户端发送消息(write_message)?例如,假设我的程序正在监视一个目录,以查看文件是否出现/存在。当它出现时,我想向浏览器客户端发送一条web套接字消息,说明该文件存在。我似乎无法理解如何在不首先接收websocket消息(在消息处理程序上)的情况下调用“write_message”方法 即使我使用“PeriodicCallback”方法,我仍然不清楚如何实际调用“write_message”方法。有没有关于如何在

我是Tornado的新手,我想知道是否可以在Python程序中随意向所有客户端发送消息(write_message)?例如,假设我的程序正在监视一个目录,以查看文件是否出现/存在。当它出现时,我想向浏览器客户端发送一条web套接字消息,说明该文件存在。我似乎无法理解如何在不首先接收websocket消息(在消息处理程序上)的情况下调用“write_message”方法


即使我使用“PeriodicCallback”方法,我仍然不清楚如何实际调用“write_message”方法。有没有关于如何在不在“on_message”处理程序中调用“write_message”的示例?

您需要保留一个打开的WebSocket集合,并随意迭代该集合以发送消息

例如,每当客户端连接到您的.domain.example/test/时,我都会发送一条消息,但无论何时您想要发送内容,这个想法都是一样的:

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()
显然,您需要使用以下JavaScript在浏览器中创建websocket:

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

并对其进行相应的管理。

Eww。您必须将
self
保存到全局变量。我想知道是否有更好的方法来实现这一点。@CollinBell您可以始终为
集合使用class变量
,并将send函数转换为
@classmethod
;)