如何使用 Tornado 监听来自多个地方的传入 websocket 消息?

Posted

技术标签:

【中文标题】如何使用 Tornado 监听来自多个地方的传入 websocket 消息?【英文标题】:How to listen for incoming websocket messages from multiple places using Tornado? 【发布时间】:2016-12-10 17:23:14 【问题描述】:

假设我有一个无限的 while 循环等待 WebSocket Tornado 客户端连接的 read_message() 方法。然后,我在外部触发了一个发送消息并应立即得到响应的函数。 由于一切都是异步的,我会假设当外部调用发生时,执行会转到它。但是当我尝试在该调用中侦听响应时,它会抛出一个AssertionError,指出self.read_future 不是None,而它应该是。

以下是客户端应用程序的方法。早些时候,它连接到服务器并将连接放在self.conn 变量中:

async def loop(self):
    while True:
        print(await self.conn.read_message())

async def ext_call(self):
    self.conn.write_message('Hello, World!')
    response = await self.conn.read_message()  # This line fails

为什么我不能在两个不同的地方收听消息?

【问题讨论】:

【参考方案1】:

您的要求是模棱两可的 - 哪些消息会发送到哪个位置?看起来您可能意味着在您发送“Hello world”之后到达下一条消息以在ext_call 中处理,而所有其他消息将在loop 中打印。但是系统怎么会知道呢?考虑到“Hello world”消息可以在python解释器执行ext_call中的read_message调用之前发送到客户端并收到响应,因此它将被路由到等待的@ 987654325@loop

通常,您希望使用其中一种模式,但不能同时使用两种模式。如果您总是有匹配的请求/响应对消息,您可以在发送后阅读ext_call。但是,如果您可能有不属于请求/响应对的消息,则需要 one 循环来读取所有消息并决定如何处理它们(也许按类型将它们拆分并发出使用tornado.queues 模块在一个或多个队列上)。

【讨论】:

Python的queue.Queuetornado.queues.Queue有区别吗? 是 - queue.Queue 有一个同步接口并且是线程安全的; tornado.queues.Queue 有一个异步接口并且不是线程安全的。 Tornado 应用程序应该使用异步 tornado.queues.Queue,除非您需要与非 Tornado 线程通信(在这种情况下,queue.Queue 有时是合适的,但您只能使用来自 Tornado 线程的 _nowait 方法)。跨度>

以上是关于如何使用 Tornado 监听来自多个地方的传入 websocket 消息?的主要内容,如果未能解决你的问题,请参考以下文章

使用具有多个模块的模块模式,一个模块中的事件监听器如何使用来自另一个模块的回调?

Tornado 为一个请求推送多个响应

同时使用 Python Tornado 后端、WebSocket 监听器和 MQTT 客户端

如何在 Tornado 中创建多个 websocket 聊天?

我如何在 smack openfire android 中监听传入的订阅请求

如何让 XAMPP Apache 监听多个网络端口?