我正在实现一个快速异步REST接口调用程序,我希望以同步方式上传数据。现在我要构建异步框架,它只是以异步方式调用python页面并测量延迟。
以下是代码(不能如下所述):
import aiohttp
import asyncio
import async_timeout
from timeit import default_timer as timer
async def fetch(session, url):
start = timer()
with async_timeout.timeout(10):
async with session.get(url) as response:
date = response.headers.get("DATE")
end = timer()
delay = end - start
print("{}:{} with delay {} s".format(date, response.url, delay))
return await response.read()
async def bound_call(semaphore, session, url):
async with semaphore:
await fetch(session, url)
async def perform_call(session):
sem = asyncio.Semaphore(1000)
html = await bound_call(sem, session, 'http://python.org')
async def perform_calls(n):
tasks = []
async with aiohttp.ClientSession() as session:
for i in range(n):
task = perform_call(session)
tasks.append(task)
responses = asyncio.gather(*tasks)
await responses
call_number = 10
loop = asyncio.get_event_loop()
loop.run_until_complete(perform_calls(call_number))
只要我使用
,它就能正常工作await perform_call(session)
但这显然打破了异步电话。如果我用
替换它 task = perform_call(session)
tasks.append(task)
responses = asyncio.gather(*tasks)
await responses
让它同时等待所有回复,我得到以下错误:
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host python.org:80 ssl:False [Network is unreachable]
我尝试将其作为jupyter笔记本中的代码运行,并且由于它没有运行,因此将其复制到普通代码中。在这两种情况下,它都运行在python 3.5上。不幸的是,我找不到问题的解决方案。一旦我尝试使用聚集,似乎没有网络访问权限。有没有人建议为什么它不起作用?我很高兴有任何建议。
答案 0 :(得分:4)
好的,我在一个问题中找到答案,我的问题是重复的(我在这里发布后才找到副本。)
解决方案是使用以下方法初始化客户端会话:
import socket # together with your other imports
conn = aiohttp.TCPConnector(
family=socket.AF_INET,
verify_ssl=False,
)
# Create client session that will ensure we dont open new connection
# per each request.
async with aiohttp.ClientSession(connector=conn) as session:
基于副本的说明:
客户端会话将使用连接而不是默认的AsyncResolver作为连接的解析程序。它曾经是默认的解析器。问题似乎与ipv6的域有关,其中AsyncResolver存在问题,因此解决方案是简单地将族指定为ipv4地址,这就是我们对family=socket.AF_INET
的处理。
重复:python 3.5 asyncio and aiohttp Errno 101 Network is unreachable