10

我想将 tornado 与 aiohttp 和本机 python 3.5 协程等异步库一起使用,最新的 tornado 版本(4.3)似乎支持它。但是,在龙卷风事件循环中使用它时,请求处理程序会无限期挂起。当不使用 aiohttp 时(即没有下面的行) r = await aiohttp.get('http://google.com/')text = await r.text()请求处理程序照常进行。

我的测试代码如下:

from tornado.ioloop import IOLoop
import tornado.web
import tornado.httpserver
import aiohttp

IOLoop.configure('tornado.platform.asyncio.AsyncIOLoop')


class MainHandler(tornado.web.RequestHandler):
    async def get(self):
        r = await aiohttp.get('http://google.com/')
        text = await r.text()
        self.write("Hello, world, text is: {}".format(text))

if __name__ == "__main__":
    app = tornado.web.Application([
        (r"/", MainHandler),
    ])
    server = tornado.httpserver.HTTPServer(app)
    server.bind(8888, '127.0.0.1')
    server.start()
    IOLoop.current().start()
4

2 回答 2

14

根据docs,您几乎做对了。您必须使用相应的 asyncio 创建/初始化 Tornado 的 ioloop,因为 aiohttp 在 asyncio 上运行。

from tornado.ioloop import IOLoop
import tornado.web
import tornado.httpserver
import aiohttp
from tornado.platform.asyncio import AsyncIOMainLoop
import asyncio

class MainHandler(tornado.web.RequestHandler):
    async def get(self):
        r = await aiohttp.get('http://google.com/')
        text = await r.text()
        self.write("Hello, world, text is: {}".format(text))

if __name__ == "__main__":
    AsyncIOMainLoop().install()
    app = tornado.web.Application([
        (r"/", MainHandler),
    ])
    server = tornado.httpserver.HTTPServer(app)
    server.bind(1234, '127.0.0.1')
    server.start()
    asyncio.get_event_loop().run_forever()

你的代码卡住的原因是 asyncio 的 ioloop 实际上没有运行,只有 Tornado 的,所以await无限期地等待。

于 2016-01-13T23:44:52.573 回答
4

从 Tornado 5开始,它的大部分异步函数、类和装饰器,包括IOLoop,不仅与 Python 的标准兼容asyncio,而且在 Python 3.5+ 上运行时是其对应物的别名。

这意味着当您使用 Tornado 之类的东西时IOLoop()@gen.coroutineTornado 在幕后使用asyncio.

这样你就可以使用IOLoop.current().start(),你会得到asyncioioloop.

于 2019-02-27T09:13:35.157 回答