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() 循环不起作用

Asyncio RuntimeError:事件循环已关闭

Discord Python 异步事件循环已关闭

Python Asyncio - RuntimeError:无法关闭正在运行的事件循环

ipython在最新python版本中出现事件循环问题