将龙卷风与 aiohttp(或其他基于异步的库)一起使用
Using tornado with aiohttp (or other asyncio-based libraries)
我想将 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()
根据 docs,您的做法几乎是正确的。你必须 create/init Tornado 的 ioloop 和相应的 asyncio,因为 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
无限期地等待。
从 Tornado 5 开始,它的大部分异步函数 类 和装饰器,包括 IOLoop
,不仅 兼容 与 Python 的标准 asyncio
,但是当 Python 上的 Python 3.5+ 时 别名 .
这意味着当您使用 Tornado 的 IOLoop()
、@gen.coroutine
之类的东西时,Tornado 在幕后使用等效函数和 asyncio
中的 类。
这样您就可以使用 IOLoop.current().start()
并获得 asyncio
的 ioloop。
我想将 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()
根据 docs,您的做法几乎是正确的。你必须 create/init Tornado 的 ioloop 和相应的 asyncio,因为 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
无限期地等待。
从 Tornado 5 开始,它的大部分异步函数 类 和装饰器,包括 IOLoop
,不仅 兼容 与 Python 的标准 asyncio
,但是当 Python 上的 Python 3.5+ 时 别名 .
这意味着当您使用 Tornado 的 IOLoop()
、@gen.coroutine
之类的东西时,Tornado 在幕后使用等效函数和 asyncio
中的 类。
这样您就可以使用 IOLoop.current().start()
并获得 asyncio
的 ioloop。