【发布时间】:2018-09-14 04:37:02
【问题描述】:
我正在尝试制作一个可以使用一天、一周或更长时间的应用。 终止应用程序的生命周期,它将向不同的 API 发出请求。其中一些 API 可能需要登录,因此重要的是 我可以随时访问 cookie。
所以我需要的是一个不同 API 可以在不阻塞应用程序的情况下使用的文件。
我是异步编程的新手(asyncio/aiohttp),我见过的示例展示了如何从 url 列表中发出大量请求,但这不是我所需要的。
我的代码的问题是,我得到 ClientSession 已关闭错误或未关闭的 ClientSession 警告。
import asyncio # only here for debugging purposes
import aiohttp
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:61.0) Gecko/20100101 Firefox/61.1'
def default_headers():
header = {
'User-Agent': USER_AGENT
}
return header
class WebSession(object):
session = None
@classmethod
def create(cls):
cls.session = aiohttp.ClientSession()
return cls.session
@classmethod
def close(cls):
if cls.session is not None:
cls.session.close()
async def request(method, url, **kwargs):
if kwargs.get('headers', None) is None:
kwargs['headers'] = default_headers()
if WebSession.session is None:
session = WebSession.create()
else:
session = WebSession.session
async with session.request(method=method, url=url, **kwargs) as response:
if isinstance(session, aiohttp.ClientSession):
# if i close the session here, i will get the ClientSession closed error on 2. request.
# await session.close()
pass
return response
async def get(url, **kwargs):
return await request('GET', url=url, **kwargs)
async def post(url, **kwargs):
return await request('POST', url=url, **kwargs)
async def get_url():
res = await get('https://httpbin.org/get')
print(f'Status code: {res.headers}')
m_loop = asyncio.get_event_loop()
m_loop.run_until_complete(get_url())
# if i run this without closing the ClientSession, i will get unclosed ClientSession warnings.
m_loop.run_until_complete(get_url())
m_loop.close()
我确实收到了来自服务器的响应,但随后出现此错误/警告
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x03354630>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x033BBBF0>, 71.542)]']
connector: <aiohttp.connector.TCPConnector object at 0x033542D0>
如果我取消注释 await session.close() 并删除 pass,我会在第一个请求中收到来自服务器的响应,然后在第二个请求中收到 RuntimeError: Session is closed。
【问题讨论】:
-
您得到的确切错误是什么?会话是否过期或类似原因? @Gort
-
我已经用错误信息@YuvalPruss 更新了问题
-
取消注释您的关闭语句并捕获那里关闭连接的异常。这样你就知道你关闭了会话并在连接已经关闭时捕获错误。