使用龙卷风和aiohttp(或其他基于asyncio的库)

时间:2016-01-13 06:30:40

标签: python-3.x tornado python-asyncio aiohttp

我想将龙卷风与asioio库(如aiohttp和原生python 3.5协同程序)一起使用,它似乎在最新的龙卷风版本(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()

2 个答案:

答案 0 :(得分:11)

根据docs,你做的几乎是正确的。你必须使用相应的asyncio创建/ init 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().start()

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

答案 1 :(得分:0)

从Tornado 5 开始,其大多数异步函数,类和修饰符,包括IOLoop,不仅与Python的标准{{1}兼容 },但是在Python 3.5+上运行时,是别名

这意味着当您使用诸如asyncioIOLoop()之类的Tornado之类的东西时,Tornado在幕后使用@gen.coroutine中的等效函数和类。

这样,您可以使用asyncio并获得IOLoop.current().start()的ioloop。