python3.5:使用aiohttp可以很好地提供多个响应吗?

时间:2016-09-24 14:55:20

标签: asynchronous python-3.5 python-asyncio aiohttp

我正在使用aiohttp的最新版本(1.0.2)和python3.5我有以下服务器代码

import asyncio

from aiohttp.web import Application, Response, StreamResponse, run_app


async def long(request):
    resp = StreamResponse()
    name = request.match_info.get('name', 'Anonymous')
    resp.content_type = 'text/plain'
    for _ in range(1000000):
        answer = ('Hello world\n').encode('utf8')

        await resp.prepare(request)
        resp.write(answer)
    await resp.write_eof()
    return resp


async def init(loop):

    app = Application(loop=loop)
    app.router.add_get('/long', long)
    return app

loop = asyncio.get_event_loop()
app = loop.run_until_complete(init(loop))
run_app(app)

如果我在不同的终端中运行两个卷曲请求curl http://localhost:8080/long,则只有第一个会收到数据

我的想法是,使用asyncio,您可以在单线程代码中开始提供其他响应,而另一个正在等待I / O

我在网上找到的关于concurent + asyncio的大部分代码都只涉及客户端,而不是服务器端

我是否遗漏了某些内容,或者我是否理解asyncio的工作方式存在缺陷?

1 个答案:

答案 0 :(得分:2)

只需在await resp.drain()之后推送resp.write(),即可让aiohttp有机会在任务之间切换:

import asyncio

from aiohttp.web import Application, Response, StreamResponse, run_app


async def long(request):
    resp = StreamResponse()
    name = request.match_info.get('name', 'Anonymous')
    resp.content_type = 'text/plain'
    await resp.prepare(request)  # prepare should be called once
    for _ in range(1000000):
        answer = ('Hello world\n').encode('utf8')

        resp.write(answer)
        await resp.drain()  # switch point
    await resp.write_eof()
    return resp


async def init(loop):

    app = Application(loop=loop)
    app.router.add_get('/long', long)
    return app

loop = asyncio.get_event_loop()
app = loop.run_until_complete(init(loop))
run_app(app)