与 python3 asyncio 建立连接

Posted

技术标签:

【中文标题】与 python3 asyncio 建立连接【英文标题】:Making connections with python3 asyncio 【发布时间】:2015-05-27 13:45:28 【问题描述】:

我正在尝试同时连接到多个服务器。我目前正在使用loop.create_connection,但它在第一个无响应的服务器处冻结。

gsock = loop.create_connection(lambda: opensock(sid), server, port)
transport, protocol = loop.run_until_complete(gsock)

我尝试对此进行线程化,但它在使用的 sid 值以及各种错误(例如 RuntimeError: Event loop is runningRuntimeError: Event loop stopped before Future completed)方面产生了问题。另外,根据我的变量(虽然混淆了),当transport, protocol = loop.run_until_complete(gsock) 抛出异常时,协议的connection_made() 方法会被执行。

我对 asyncio 模块不太了解,所以请尽可能全面。我认为我不需要读取器/写入器变量,因为读取应该自动完成并触发data_received() 方法。

谢谢。

【问题讨论】:

【参考方案1】:

您可以通过同时调度所有协程来同时连接到多个服务器,而不是使用loop.run_until_complete 单独建立每个连接。一种方法是使用asyncio.gather 来安排它们并等待它们完成:

import asyncio

# define opensock somewhere

@asyncio.coroutine
def connect_serv(server, port):
    try:
        transport, protocol = yield from loop.create_connection(lambda: opensock(sid), server, port)
    except Exception:
        print("Connection to : failed".format(server, port))

loop = asyncio.get_event_loop()
loop.run_until_complete(
    asyncio.gather(
      connect_serv('1.2.3.4', 3333),
      connect_serv('2.3.4.5', 5555),
      connect_serv('google.com', 80),
 ))
loop.run_forever()

这将同时启动对gather的调用中列出的所有三个协程,这样如果其中一个挂起,其他的就不会受到影响;他们将能够在其他连接挂起时继续他们的工作。然后,如果它们都完成了,loop.run_forever() 将被执行,这将允许您的程序继续运行,直到您停止循环或终止程序。

您提到的reader/writer 变量只有在您使用asyncio.open_connection 连接到服务器时才相关,而不是create_connection。它使用 Stream API,这是一个比create_connection 使用的基于协议/传输的 API 更高级别的 API。真正由您决定您喜欢使用哪个。 asyncio 文档中有 examples 和 both,如果您想查看比较。

【讨论】:

非常感谢,我会试试你的技术。 我仍然想知道在 run_forever() 运行时是否可以使用 run_until_complete()。我想我会在重写后尝试。 实际上这不是一个可行的解决方案,因为套接字不是完全活动的(除非所有服务器连接都及时成功)。程序挂起,等待与服务器的连接之一。 @baudsmoke 我不确定你的意思。哪些套接字未完全激活?具体是什么挂?该程序旨在阻止run_until_complete 调用,如果对connect_serv 的调用之一永远不会返回,则可能永远阻塞。但是,未挂起的 connect_serv 调用应该可以继续正常工作。

以上是关于与 python3 asyncio 建立连接的主要内容,如果未能解决你的问题,请参考以下文章

Python 3.5.1 - Asyncio - 检查套接字客户端是不是已断开连接

深究Python中的asyncio库-asyncio简介与关键字

我如何将crossbar客户端(python3,asyncio)与tkinter集成

python asyncio 异步 I/O - 协程(Coroutine)与运行

Python协程之asyncio

Python3异步编程