python aiohttp进入现有的事件循环
Posted
技术标签:
【中文标题】python aiohttp进入现有的事件循环【英文标题】:python aiohttp into existing event loop 【发布时间】:2018-11-25 08:33:45 【问题描述】:我正在测试 aiohttp 和 asyncio。我希望同一个事件循环有一个套接字、http 服务器、http 客户端。
我正在使用这个示例代码:
@routes.get('/')
async def hello(request):
return web.Response(text="Hello, world")
app = web.Application()
app.add_routes(routes)
web.run_app(app)
问题是run_app
被阻塞。我想将 http 服务器添加到我创建的现有事件循环中:
asyncio.get_event_loop()
【问题讨论】:
【参考方案1】:问题是
run_app
被阻塞。我想将 http 服务器添加到现有的事件循环中
run_app
只是一个方便的 API。要挂钩现有的事件循环,您可以直接实例化AppRunner
:
loop = asyncio.get_event_loop()
# add stuff to the loop
...
# set up aiohttp - like run_app, but non-blocking
runner = aiohttp.web.AppRunner(app)
loop.run_until_complete(runner.setup())
site = aiohttp.web.TCPSite(runner)
loop.run_until_complete(site.start())
# add more stuff to the loop
...
loop.run_forever()
在 asyncio 3.8 及更高版本中,您可以使用asyncio.run()
:
async def main():
# add stuff to the loop, e.g. using asyncio.create_task()
...
runner = aiohttp.web.AppRunner(app)
await runner.setup()
site = aiohttp.web.TCPSite(runner)
await site.start()
# add more stuff to the loop, if needed
...
# wait forever
await asyncio.Event().wait()
asyncio.run(main())
【讨论】:
谢谢,为什么服务器不会在 SIGINT 上终止(按 CTRL+C)?我正在使用 windows powershell @user3599803 不使用 Windows,抱歉,但谷歌搜索可能会在 asyncio 中显示为 a long-standing issue。 @user3599803 ***.com/a/37420223/2955584 检查此答案以终止 Windows 机器中的脚本【参考方案2】:对于来自 Google 的未来旅行者,这里有一个更简单的方法。
async def main():
await aio.gather(
web._run_app(app, port=args.port),
SomeotherTask(),
AndAnotherTask()
)
aio.run(main())
说明:
web.runapp
是对内部函数 web._runapp
的薄包装。该函数使用旧式方式获取事件循环,然后调用loop.run_until_complete
。
我们将其替换为 aio.gather
以及我们希望同时运行的其他任务,并使用 aio.run
来安排它们
Source
【讨论】:
他们现在提供 Application Runner API 以支持此用例:docs.aiohttp.org/en/stable/… 请避免在 *** 答案中使用私有 API。以_
开头的方法,例如_run_app
,可以在不事先通知的情况下被删除、重命名或更改含义。以上是关于python aiohttp进入现有的事件循环的主要内容,如果未能解决你的问题,请参考以下文章
Flask asyncio aiohttp - RuntimeError:线程'Thread-2'中没有当前事件循环
jQuery - 在现有的 each() 事件中嵌套另一个 each() 循环不起作用