如何在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)