如何知道StreamReader准备就绪的时间? [英] How to know when StreamReader is ready?

查看:102
本文介绍了如何知道StreamReader准备就绪的时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用asyncio建立TCP连接:

I'm using asyncio to make TCP connections:

reader, writer = await asyncio.open_connection(addr)

我需要保持连接活跃.为此,我要存储一对(reader, writer)以便将来进行通信.但是,我不知道什么时候reader有要读取的数据.我该怎么办?当阅读器准备就绪时,有没有办法制作处理程序?

I need to keep connections alive. For this, I'm storing a pair of (reader, writer) for future communications. However, I don't know when reader has data to read. What can I do with it? Is there a way to make a handler, when the reader is ready?

推荐答案

但是,我不知道reader何时需要读取数据.我该怎么办?

However, I don't know when reader has data to read. What can I do with it?

知道读取器流何时有数据读取的一种明显方法是await:

The obvious way to know when a reader stream has data to read is to await it:

data = await reader.read(1024)

这将立即返回数据,或者暂停当前协程,从而允许其他协程取得进展,并且仅在读取器具有一些要读取的数据时才恢复该协程.无需存储读取器/写入器以用于将来的通信,您可以编写用于执行通信的协程,并存储

This will either return the data right away, or suspend the current coroutine, allowing other coroutines to make progress, and only resuming this one when the reader has some data to read. Instead of storing the reader/writer for future communication, you can write a coroutine that does the communication, and store the task that drives it:

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 流API 背后的想法是写这样的具有顺序外观的代码,将其留给asyncio来处理文件描述符的轮询和任务调度.您可以使用 asyncio.gather asyncio.wait 可以并行运行数千个此类轻量级协程.

The idea behind the asyncio stream API is to write such sequential-looking code, leaving it to asyncio to handle polling of file descriptors and scheduling of tasks. You can use combinators like asyncio.gather and asyncio.wait to run thousands of such lightweight coroutines in parallel.

当阅读器准备就绪时,有没有办法制作处理程序?

Is there a way to make a handler, when the reader is ready?

如果您需要基于回调的API,则可能应使用较低级别的

If you need a callback-based API, you should probably use the lower-level transports and protocols instead. However, if you are already working with streams, but still occasionally need an ordinary callback, you can get it by obtaining a Future:

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

未来具有与协程处理程序等效的角色.一旦 read 将不再阻止,完成的回调将由事件循环使用单个参数Future调用.未来将结束,它的 result() 方法可用于检索收到的数据或异常.

Future has the role equivalent to a coroutine handler. Once read would no longer block, the done-callback will be invoked by the event loop with a single argument, the future. The future will have finished, and its result() method can be used to retrieve the received data or an exception.

(以上内容适用于asyncio中的任何协程或将来兼容的对象,而不仅适用于 StreamReader 方法.)

(The above applies to any coroutine or future-compatible object in asyncio, not just to StreamReader methods.)

这篇关于如何知道StreamReader准备就绪的时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆