如何知道StreamReader何时准备就绪?



我正在使用asyncio进行TCP连接:

reader, writer = await asyncio.open_connection(addr)

我需要保持连接。为此,我存储了一对(reader, writer)以供将来通信。但是,我不知道reader什么时候有数据要读取。我能用它做什么?当读者准备好时,有没有办法制作处理程序?

但是,我不知道reader什么时候有数据要读取。我能用它做什么?

了解读取器流何时有要读取的数据的明显方法是await它:

data = await reader.read(1024)

这将立即返回数据,或暂停当前协程,允许其他协程取得进展,并且仅在读取器有一些数据要读取时才恢复此协程。您可以编写一个执行通信的协程,并存储驱动通信的任务,而不是存储读取器/写入器以供将来通信:

async def communicate():
reader, writer = await asyncio.open_connection(addr)
# an echo server
while True:
line = await reader.readline()
if not line:
break
writer.write(line)
await writer.drain()  # backpressure, see https://tinyurl.com./hqylfay
task = loop.create_task(communicate())
# the task can itself be awaited, canceled, etc.

asyncio stream API 背后的想法是编写这种顺序代码,让它让 asyncio 处理文件描述符的轮询和任务调度。您可以使用asyncio.gatherasyncio.wait等组合器并行运行数千个此类轻量级协程。

当读者准备好时,有没有办法制作处理程序?

如果需要基于回调的 API,则可能应改用较低级别的传输和协议。但是,如果你已经在使用流,但偶尔仍然需要一个普通的回调,你可以通过获取一个Future来获取它:

future = asyncio.ensure_future(reader.read(1024))
future.add_done_callback(your_callback)

Future 具有等效于协程处理程序的角色。一旦read不再阻塞,done-callback 将由事件循环使用单个参数调用,即 future。将来将完成,其result()方法可用于检索接收的数据或异常。

(上述内容适用于 asyncio 中的任何协程或未来兼容的对象,而不仅仅是StreamReader方法。

最新更新