如何在Tornado for WebSocket中使用Python 3.5样式的异步和等待?
请考虑以下简短片段:如何在Tornado for WebSocket中使用Python 3.5样式的异步和等待?,python,websocket,tornado,Python,Websocket,Tornado,请考虑以下简短片段: import tornado import tornado.websocket import tornado.ioloop import tornado.gen import tornado.web class NewWsHandler(tornado.websocket.WebSocketHandler): async def on_message(self, message): await self.write_message("echo "
import tornado
import tornado.websocket
import tornado.ioloop
import tornado.gen
import tornado.web
class NewWsHandler(tornado.websocket.WebSocketHandler):
async def on_message(self, message):
await self.write_message("echo " + message)
class OldWsHandler(tornado.websocket.WebSocketHandler):
@tornado.gen.coroutine
def on_message(self, message):
yield self.write_message("echo " + message)
app = tornado.web.Application([(r'/', OldWsHandler)])
app.listen(8080)
tornado.ioloop.IOLoop.current().start()
OldWsHandler
使用3.5之前的方法在Tornado中执行异步函数,并且工作正常。然而,为了可读性和速度,最好使用它
文件说:
只需使用async def foo()
代替带有@gen.coroutine
装饰器的函数定义,并使用wait
代替yield
所以我写了NewWsHandler
。但是,在发送websocket消息时,会发出警告:
/usr/lib/python3.5/site-packages/tornado/websocket.py:417: RuntimeWarning: coroutine 'on_message' was never awaited
callback(*args, **kwargs)
但这仍然看起来像黑客,似乎与文档相矛盾。正确的做法是什么
注意:我使用的是Python 3.5.1和Tornado 4.3。协同程序的调用不同于常规函数;因此,当子类化和重写方法时,您不能将基类中的常规方法更改为子类中的协同程序(除非基类明确表示这是可以的)<代码>WebSocketHandler.on_消息可能不是一个协同程序(从Tornado 4.3开始;这可能在将来发生变化) 相反,如果您需要对消息执行异步操作,请将异步部分放在单独的函数中,并使用
IOLoop.current().spawn\u回调调用它。(或者如果write_message
是您正在做的唯一异步操作,只需同步调用它即可)
更新
这在Tornado 4.5中有所改变,WebSocketHandler.on_message
现在可以用作协同程序。请参阅。是否有某种方法可以查询数据库(异步)以响应websocket消息?类似于result=wait query(…)
?我似乎找不到一个真正好的方法来做这件事。(除了我问题中的“黑客”之外)。一旦你产生了一个单独的回调,你可以做任何你想做的事情。您只需小心处理异常,因为此处引发的任何异常都不会通过\u消息上的,并影响websocket连接。还要注意,在前一条消息完成之前,可能会收到另一条消息;为了避免这种情况,您可能希望在\u open()
上的中生成回调,并使用队列与之通信。
class NewWsHandler(tornado.websocket.WebSocketHandler):
def finish(self):
pass
@tornado.web.asynchronous
async def on_message(self, message):
await self.write_message("echo " + message)