我正在尝试制作一个通常向服务器发送请求并接收响应的应用程序。如果仅此而已,我会选择 HTTP 并称之为交易。但是一些对服务器的请求对其他客户端进行了更改,所以我希望服务器向所有受影响的客户端发送一条消息,要求它们更新。
为此,我选择了 WebSockets 协议(protocol)和 Tornado 库来使用 Python 来处理它。尽管存在异步,但简单的消息交换非常简单。然而,WebSocket 客户端实际上并不是那么可配置,我一直在努力让客户端监听传入的通知,而不会中断主消息交换。
服务器部分由 tornado.websocket.WebSocketHandler
表示,它有一个 on_message
方法:
from tornado.websocket import WebSocketHandler
class MyHandler(WebSocketHandler):
def on_message(self, message):
print('message:', message)
我想要在客户端部分有类似的东西,它只由一个函数表示 tornado.websocket.websocket_connect
(source)。此函数启动一个 tornado.websocket.WebSocketClientConnection
( source ) 对象,它有一个 on_message
方法,但由于纠缠的异步结构,我无法在不中断主要消息交换的情况下正确覆盖它。
我尝试采用的另一种方法是 on_message_callback
。这听起来像是我可以使用的东西,但我不知道如何将它与 read_message
一起使用。这是我最好的尝试:
import tornado.websocket
import tornado.ioloop
ioloop = tornado.ioloop.IOLoop.current()
def clbk(message):
print('received', message)
async def main():
url = 'server_url_here'
conn = await tornado.websocket.websocket_connect(url, io_loop = ioloop, on_message_callback=clbk)
while True:
print(await conn.read_message()) # The execution hangs here
st = input()
conn.write_message(st)
ioloop.run_sync(main)
这是服务器代码:
import tornado.ioloop
import tornado.web
import tornado.websocket
import os
class EchoWebSocket(tornado.websocket.WebSocketHandler):
def open(self):
self.write_message('hello')
def on_message(self, message):
self.write_message(message)
self.write_message('notification')
if __name__ == "__main__":
app = tornado.web.Application([(r"/", EchoWebSocket)])
app.listen(os.getenv('PORT', 8080))
tornado.ioloop.IOLoop.current().start()
我不知道这里发生了什么。我什至在朝着正确的方向前进吗?
最佳答案
这里有两个问题:
- 使用
on_message_callback
或循环await read_message()
,但不能同时使用。如果您提供回调,则消息只会传递给该回调,而不会保存以供 read_message 使用。 input
是阻塞的,不能很好地与 Tornado 配合使用。在这个小玩具演示中很好,但如果你想在生产中做这样的事情,你可能想要做一些事情,比如在sys.stdin
周围包装一个PipeIOStream
并使用stream.read_until('\n')
。
关于python - 如何让 Tornado websocket 客户端接收服务器通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40959113/