我想要快速连接到很多不同的网站列表。我正在使用异步编程(asyncio)以异步方式进行此操作,现在希望添加一些超时设置,以便在连接等待时间过长时忽略这些连接。
我该如何实现这个功能?
import ssl
import asyncio
from contextlib import suppress
from concurrent.futures import ThreadPoolExecutor
import time
@asyncio.coroutine
def run():
while True:
host = yield from q.get()
if not host:
break
with suppress(ssl.CertificateError):
reader, writer = yield from asyncio.open_connection(host[1], 443, ssl=True) #timout option?
reader.close()
writer.close()
@asyncio.coroutine
def load_q():
# only 3 entries for debugging reasons
for host in [[1, 'python.org'], [2, 'qq.com'], [3, 'google.com']]:
yield from q.put(host)
for _ in range(NUM):
q.put(None)
if __name__ == "__main__":
NUM = 1000
q = asyncio.Queue()
loop = asyncio.get_event_loop()
loop.set_default_executor(ThreadPoolExecutor(NUM))
start = time.time()
coros = [asyncio.async(run()) for i in range(NUM)]
loop.run_until_complete(load_q())
loop.run_until_complete(asyncio.wait(coros))
end = time.time()
print(end-start)
(顺便说一句:有人知道如何优化这个吗?)
load_q
函数中的对q.put(None)
的调用上使用yield from
,因此当前代码无法正常工作。 - danoasyncio.create_connection
和Protocol
(它在建立连接后立即关闭网络连接)。这是一个代码示例,我在百万Alexa站点列表上尝试过(可能稍微有些过时,例如没有使用一些方便函数,如asyncio.wait_for()
)。它只使用一个线程并最多打开limit
个ssl连接。 - jfs