我试图创建一个通常向服务器发送请求并收到响应的应用程序。如果它只是那样,我会使用HTTP并称之为交易。但是对服务器的一些请求会对其他客户端进行更改,因此我希望服务器向所有受影响的客户端发送他们应该更新的消息。 为此,我选择了WebSockets协议和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()
我不知道这里发生了什么。我是否正朝着正确的方向前进?
答案 0 :(得分:1)
这里有两个问题:
on_message_callback
或循环await read_message()
,但不能同时使用两者。如果您提供回调,则消息将仅传递给该回调,而不会保存以供read_message使用。input
正在阻止,并且与Tornado不能很好地配合。这个小玩具演示很好但是如果你想在制作中做这样的事情,你可能想做一些事情,比如在PipeIOStream
周围包裹一个sys.stdin
并使用{{ 1}}。