首页 > 解决方案 > 获取 ServerDisconnectedError 异常,Connection.release() 会帮助解决这个问题吗?

问题描述

我的代码遇到了一些问题。我有一个客户端会话,它通过请求与网站通信。

问题是,当我长时间运行代码时,我开始出现一些错误,例如ClientResponseError, ServerDisconnectedError, Error 101. 所以我正在阅读文档,我看到了这个:

release()
将连接释放回连接器。
底层套接字未关闭,如果连接超时(默认为 30 秒)未过期,则可以稍后重用连接。

但我不明白。有人可以简单地解释一下吗?它会解决我的问题吗?

session = aiohttp.ClientSession(cookie_jar=cookiejar)
while True:
    await session.post('https://anywhere.com', data={'{}': ''})

标签: pythonpython-asyncioaiohttp

解决方案


当您连接的服务器过早关闭连接时会引发异常。它发生了。但是,释放与池的连接并不能解决此问题,并且您发布的代码已经释放了连接,尽管是隐式的。相反,您需要处理异常,您的应用程序需要决定如何处理此错误。

您可能希望将响应对象用作上下文管理器,这将有助于在您不再需要访问响应数据时更早地释放连接。您的示例代码不使用session.post()协程的返回值,因此当 Python 从内存中删除它时,连接已经自动为您释放(当没有对它的引用时会发生这种情况),但是使用它作为上下文管理器可以Python 通过显式知道您不再需要它。

这是一个使用(异步)上下文管理器的简单版本,它捕获服务器断开连接时引发的异常等等:

with aiohttp.ClientSession(cookie_jar=cookiejar) as session:
    while True:
        try:
            async with session.post('https://anywhere.com', data={'{}': ''}) as response:
                # do something with the response if needed

            # here, the async with context for the response ends, and the response is
            # released.
        except aiohttp.ClientConnectionError:
            # something went wrong with the exception, decide on what to do next
            print("Oops, the connection was dropped before we finished")
        except aiohttp.ClientError:
            # something went wrong in general. Not a connection error, that was handled
            # above.
            print("Oops, something else went wrong with the request")

我选择了 catch ClientConnectionError,它是一个ServerDisconnectedError派生的基类,但是捕获这个异常可以让你用同一个异常处理程序处理更多的连接错误情况。查看异常层次结构以帮助您决定要捕获哪些异常,这取决于您认为需要多少细节。


推荐阅读