使用asyncio作为套接字服务器的推荐方法是:
import asyncio
async def handle_client(reader, writer):
request = (await reader.read(100)).decode()
response = "Data received."
writer.write(response.encode())
async def main():
loop.create_task(asyncio.start_server(handle_client, 'localhost', 15555))
loop = asyncio.get_event_loop()
loop.create_task(main())
loop.run_forever()
这个工作很好,但现在我需要接收适当的客户端请求,然后使用aiohttp库从第三方restful API获取数据。
这需要创建一个会话变量,如下所示:
from aiohttp import ClientSession
session = ClientSession()
但这也应该放在协程内部,所以我会把它放在主函数里:
但是这也应该在一个协程中,所以我将把它放在主函数中:
async def main():
session = ClientSession()
loop.create_task(asyncio.start_server(handle_client, '', 55555))
现在我需要将会话变量传递给aiohttp get协程来获取剩余的API数据。
现在我需要将会话变量传递给aiohttp get协程来获取剩余的API数据:
async with session.get(url, params=params) as r:
try:
return await r.json(content_type='application/json')
except aiohttp.client_exceptions.ClientResponseError:
....
我的问题是,如果handle_client协程坚持仅具有reader、writer参数,并且全局变量对我没有帮助,因为会话必须存在于协程内部,那么如何将会话变量传递给handle_client协程?
start_server
的情况下,明确记录了它的回调可以是一个普通的回调函数。但在这种情况下,lambda 调用协程(这是合法的 - 你会得到协程对象)并返回结果协程对象。这使其在功能上等同于协程函数,并且它可以正常工作。当然,你是正确的,lambda 不是一个真正的协程,例如它不能包含await
。 - user4815162342handle_client
也应该是一个协程。 - user4815162342main()
协程中创建它,就像你的代码一样。创建的实例被传递给ClientContext
构造函数,但这并不重要。 - user4815162342ClientSession
只关心在创建它时是否有 某个 协程正在运行(代码似乎证实了这一点)。换句话说,即使在ClientContext.__init__
中实例化ClientSession
,也不会有任何警告。 - user4815162342