我正在使用 asyncio
建立 TCP 连接:
reader, writer = await asyncio.open_connection(addr)
我需要保持连接。为此,我存储了一对(reader,writer)
以供将来通信。但是,我不知道 reader
什么时候有数据要读取。我能用它做什么?当读者准备好时,有没有办法制作处理程序?
最佳答案
However, I don't know when
reader
has data to read. What can I do with it?
了解读取器流何时有数据要读取的明显方法是等待
它:
data = await reader.read(1024)
这将立即返回数据,或者暂停当前协程,允许其他协程取得进展,并且仅在读取器有一些数据要读取时才恢复此协程。您可以编写一个执行通信的协程,并存储 task,而不是存储读取器/写入器以供将来通信。驱动它的因素:
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.gather
的组合器和 asyncio.wait
并行运行数千个这样的轻量级协程。
Is there a way to make a handler, when the reader is ready?
如果您需要基于回调的 API,您可能应该使用较低级别的 transports and protocols反而。但是,如果您已经在使用流,但偶尔仍需要普通回调,则可以通过获取 Future
来获取它。 :
future = asyncio.ensure_future(reader.read(1024))
future.add_done_callback(your_callback)
Future 的作用相当于协程处理程序。一次read
将不再阻塞,完成回调将由事件循环使用单个参数 future 调用。 future 已经结束了,它的result()
方法可用于检索接收到的数据或异常。
(以上内容适用于 asyncio 中的任何协程或 future 兼容对象,而不仅仅是 StreamReader
方法。)
关于python - 如何知道 StreamReader 何时准备就绪?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50237676/