使用aiohttp / asyncio的异步HTTP调用失败,并显示“无法连接到主机[网络无法访问]”

时间:2017-12-28 12:22:07

标签: python python-3.x python-asyncio aiohttp

我正在实现一个快速异步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上。不幸的是,我找不到问题的解决方案。一旦我尝试使用聚集,似乎没有网络访问权限。有没有人建议为什么它不起作用?我很高兴有任何建议。

1 个答案:

答案 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