对于任何一个Asyncio新手都有同样的问题,我自己找到了解决方案。
首先,最好使用异步的高级方面--
streams
. 打电话
loop.create_connction
和
loop.create_server
被认为是低级的(我起初理解错误)。
高级替代品
create_connection
是
asyncio.open_connection
,它将为您提供一个由
asyncio.StreamReader
和
asyncio.StreamWriter
可用于读取和写入打开的连接。当数据从
StreamReader
等于
b''
或者当你发现一个例外(
ConnectionError
)当试图写信给
StreamWriter
.
高级替代品
create_server
是
asyncio.start_server
,需要提供一个回调函数,每次与服务器建立连接时都会调用该函数(打开连接,接收数据…)。回调有
流读出器
和
流写器
作为争论。连接丢失也可以通过接收来检测
B’
或
连接错误
在写信给
writer
.
多个连接可以由协程处理。服务器部分可以有一个协程(它接受来自环拓扑中一个邻居的连接),客户机部分可以有一个协程(它打开到环中另一个邻居的连接)。这个
Node
类可以如下所示:
import asyncio
class Node:
...
async def run(self):
...
self.next_reader, self.next_writer = await asyncio.open_connection(self.next_IP, self.next_port)
server_coro = asyncio.create_task(self.server_init())
client_coro = asyncio.create_task(self.client_method())
await client_coro
await server_coro
...
async def server_init(self):
server = await asyncio.start_server(self.server_callback, self.IP, self.port)
async with server:
await server.serve_forever()
async def client_method(self):
...
try:
data = await self.next_reader.read()
except ConnectionError:
...
...
注意我正在使用
asyncio.create_task
对于协程和(不在代码列表中)
asyncio.run(node.run())
被认为是
asyncio.ensure_future()
和
loop.run_forever()
. 这两个都是在python 3.7中添加的,并且
asyncio.run()
据说是临时的,所以到你读到这篇文章的时候,可能已经被别的东西取代了。
我不是一个异步专家,所以可能有一种更好、更干净的方法(如果你知道的话,请分享)。