与python3 asyncio建立联系

时间:2015-05-27 13:45:28

标签: python sockets python-3.x python-multithreading python-asyncio

我试图同时连接到多个服务器。我目前正在使用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等各种错误。另外,根据我的变量(tho混淆了),当connection_made()抛出异常时,协议的transport, protocol = loop.run_until_complete(gsock)方法会被执行。

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

谢谢。

1 个答案:

答案 0 :(得分:3)

您可以通过同时安排所有协同程序来同时连接到多个服务器,而不是使用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()将被执行,这将允许程序继续运行,直到您停止循环或终止程序。

如果您使用asyncio.open_connection连接到服务器而不是reader,则您提到的writer / create_connection个变量才有意义。它使用Stream API,它是比create_connection使用的基于协议/传输的API更高级的API。这取决于您决定使用哪种。如果您想查看比较,asyncio文档中examplesboth