如何在 Tornado 中随意发送 websocket 消息? [英] How do I send a websocket message in Tornado at will?

查看:41
本文介绍了如何在 Tornado 中随意发送 websocket 消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Tornado 很陌生,想知道是否可以从我的 Python 程序中随意向所有客户端发送消息 (write_message)?例如,假设我的程序正在监视目录以查看文件是否出现/存在.当它出现时,我想向浏览器客户端发送一条网络套接字消息,表明该文件存在.我似乎无法理解如何在没有首先收到 websocket 消息(on_message 处理程序)的情况下调用write_message"方法.

I'm very new to Tornado and wanted to know if it is possible to send a message (write_message) at will from within my Python program to all clients? For example, say my program is monitoring a directory to see if a file appears/exists. When it appears, I want to send a web socket message to a browser client that the file exists. I can't seem to understand how to invoke the "write_message" method without first receiving a websocket message (on_message handler.)

即使我使用了PeriodicCallback"方法,我仍然不清楚我实际上是如何调用write_message"方法的.是否有任何示例说明如何调用write_message"而不在on_message"处理程序中执行此操作?

Even if I use the "PeriodicCallback" method, I'm still unclear as to how I actually call the "write_message" method. Are there any examples out there of how to invoke "write_message" without doing it within the "on_message" handler?

推荐答案

你需要保留一个打开的 websockets 的集合,并随意遍历该集合以发送消息.

You need to keep a collection of openned websockets and iterate through that collection at will to send messages.

举个例子,我会在客户端连接到 your.domain.example/test/ 的任何时候发送一条消息,但无论何时你想发送一些东西,这个想法都是一样的:

As an example, I'll send a message anytime a client connect to your.domain.example/test/ but the idea is the same whenever you want to send something:

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:

You'll obviously need to create a websocket in the browser using the following JavaScript:

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

并相应地进行管理.

这篇关于如何在 Tornado 中随意发送 websocket 消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆