如何在websockets中使用python3.5风格的async和await?

2024-09-30 16:26:12 发布

您现在位置:Python中文网/ 问答频道 /正文

考虑一下这个简短的片段:

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在Tornado中使用了3.5版本之前的异步函数的方式,并且工作得很好。但是,as the documentation states,为了可读性和速度,最好使用PEP 0492。在

文件上说:

Simply use async def foo() in place of a function definition with the @gen.coroutine decorator, and await in place of yield.

所以我写了NewWsHandler。但是,在发送websocket消息时,会发出警告:

^{pr2}$

我真的不知道怎么(正确地)修理它。我试着用tornado.web.asynchronous来装饰它,但是假设是HTTP verb method。因此,在我重写finish()(websockets不允许这样做)之后,它似乎在工作:

class NewWsHandler(tornado.websocket.WebSocketHandler):
    def finish(self):
        pass

    @tornado.web.asynchronous
    async def on_message(self, message):
        await self.write_message("echo " + message)

但这看起来仍然是黑客行为,而且似乎与文档相矛盾。正确的做法是什么?在

注意:我使用的是python3.5.1和Tornado 4.3。在


Tags: importselfwebmessageasyncondefawait
1条回答
网友
1楼 · 发布于 2024-09-30 16:26:12

协程的调用方式不同于常规函数;因此,在对方法进行子类化和重写时,不能将基类中的常规方法更改为子类中的协同例程(除非基类明确说明这是可以的)。WebSocketHandler.on_message可能不是协同程序(从龙卷风4.3开始;这可能会在将来发生变化)。在

相反,如果需要在响应消息时执行异步操作,请将异步部分放在单独的函数中,并用IOLoop.current().spawn_callback调用它。(或者,如果write_message是您正在执行的唯一异步操作,则只需同步调用它)


更新

这在Tornado4.5中改变了,WebSocketHandler.on_message现在可以作为协同程序使用。见http://www.tornadoweb.org/en/stable/releases/v4.5.0.html#tornado-websocket。在

相关问题 更多 >