流
🌐 Streams
流是 QUIC 中主要的数据承载抽象。一旦会话建立,流可以由本地端点或远程端点发起。
🌐 Streams are the primary data-carrying abstraction in QUIC. A stream can be initiated by either the local endpoint or the remote peer once a session is established.
流可以是双向的(数据在两个方向流动)或单向的(数据仅在一个方向流动)。quic 模块提供了用于创建每种类型的独立 API:session.createBidirectionalStream() 和 session.createUnidirectionalStream()。由远程对等方启动的流通过 session.onstream 回调传递。
🌐 Streams can be either bidirectional (data flows in both directions) or
unidirectional (data flows in only one direction). The quic module provides
separate APIs for creating each kind:
session.createBidirectionalStream() and
session.createUnidirectionalStream(). Streams initiated by a remote
peer are delivered via the session.onstream callback.
有两种方式可以将数据写入流:
🌐 There are two ways to write data to a stream:
- 主体来源 — 在创建流时传入
body选项(或调用stream.setBody())。主体可以是字符串、ArrayBuffer、ArrayBufferView、Blob、FileHandle、AsyncIterable、同步的Iterable,或解析为这些任意类型的Promise。一个null主体会立即关闭可写端。当数据已经可用或可以表示为可迭代对象时,这是最简单的方法。 - 写入器 — 访问
stream.writer以增量推送数据。写入器提供同步方法(writeSync()、writevSync()、endSync()),这些方法会立即返回,以及异步等效方法(write()、writev()、end()),在遇到背压时会等待缓冲区排空。writeSync()在写入缓冲区已满时返回false;调用者应在重试前等待缓冲区排空。
对于给定的流,这两种方法是互斥的。
🌐 These two approaches are mutually exclusive for a given stream.
读取是通过将流作为异步可迭代对象进行迭代来完成的。每次迭代都会产生一批 Uint8Array 块:
🌐 Reading is done by iterating the stream as an async iterable. Each iteration
yields a batch of Uint8Array chunks:
for await (const chunks of stream) {
for (const chunk of chunks) {
// Process each Uint8Array chunk
}
} 每个流只能获取一个异步迭代器。该流也兼容 node:stream/iter 工具,例如 Stream.bytes()、Stream.text() 和 Stream.pipeTo()。
🌐 Only one async iterator can be obtained per stream. The stream is also
compatible with node:stream/iter utilities such as Stream.bytes(),
Stream.text(), and Stream.pipeTo().