在 aiohttp 中处理过早的客户端断开连接

Handling premature client disconnection in aiohttp

我目前正在测试 aiohttp,但我遇到了以下代码的问题:

async def index(request: web.Request) -> web.StreamResponse:
    response = web.StreamResponse(headers={'content-type': 'text/plain'})
    await response.prepare(request)
    for i in range(1000000):
        try:
            response.write(b'test response')
            await response.drain()
        except concurrent.futures.CancelledError:
            print('Remote connection closed... Cleaning up...')
            # Do cleanup process here?
            raise

    return response

现在我用下面的 curl 请求试试这个:

curl -v http://127.0.0.1:8080

然后我按 Ctrl-C 使 curl 断开连接并停止下载响应。

在 aiohttp 网络服务器的控制台日志中,我得到很多以下内容:

2017-11-08 14:42:31,295|WARNING|asyncio|socket.send() raised exception.
2017-11-08 14:42:31,295|WARNING|asyncio|socket.send() raised exception.
2017-11-08 14:42:31,295|WARNING|asyncio|socket.send() raised exception.
2017-11-08 14:42:31,295|WARNING|asyncio|socket.send() raised exception.
2017-11-08 14:42:31,295|WARNING|asyncio|socket.send() raised exception.

不断循环,我无法使用 Ctrl-C 终止服务器。我必须用 kill -KILL 杀死它才能完全终止它。客户端套接字断开连接似乎是静默处理的。我想消除 asyncio.selector_events._SelectorSocketTransport.write() 抛出的上述警告。我可以通过设置适当的记录器级别来消除它,但这不是我想要的。此外,当客户端连接终止时,我还想执行很多清理程序。我查看了 aiohttp 代码,似乎没有任何处理程序或信号可以挂钩来处理它。理想情况下,我希望能够在客户端连接关闭时进行一些清理。

在 Django 中,我可以通过使用 StreamingHttpResponse class 创建自定义 SelfCleaningStream class 来做到这一点。自定义 SelfCleaningStream class 处理 close() 方法中的清理,该方法在客户端连接关闭时由 Django 调用。

感谢报告。 这是 aiohttp 中的一个错误,我已经提交了一个 issue