需要澄清有关 Aqueduct 的流式响应

Clarification needed regarding streaming responses with Aqueduct

我正在阅读 Dart 的 Aqueduct HTTP Web 服务器文档。 在关于 streaming 响应正文的部分中,我看到以下 2 个不完全适合我的陈述:

A body object may also be a Stream<T>. Stream<T> body objects are most often used when serving files. This allows the contents of the file to be streamed from disk to the HTTP client without having to load the whole file into memory first.

When a body object is a Stream<T>, the response will not be sent until the stream is closed. For finite streams - like those from opened filed - this happens as soon as the entire file is read.

那么它是如何只在读取整个文件后才发送响应而不必先将整个文件加载到内存中的呢?

这是一个很好的问题,文档中的措辞可以改进。重要的代码在这里:https://github.com/stablekernel/aqueduct/blob/master/aqueduct/lib/src/http/request.dart#L237.

传出的 HTTP 响应也是一个流。当您向该流写入字节时,字节将通过线路传输(如果您启用缓冲,默认情况下处于启用状态,则在发送之前会建立一个缓冲区;IIRC 默认情况下为 8kb)。

您的源流——表示您的正文对象的流——通过管道传输到 HTTP 响应流(在被任何编解码器转换后,如果适用)。一旦您 return 来自控制器的 Response 对象,您的源流就会开始被使用。在源流指示它是 'closed' 之前,无法完成响应。如果您查看 FileController 的源代码,您会发现它使用 File.openRead,它会在读取所有字节后自动关闭源流。

如果您的源流是手动控制的,您可以 return 您的 Response 对象,然后将字节异步添加到流中并在完成后将其关闭。关键要点是,如果您拥有该流,则需要关闭它,系统实用程序通常会为您关闭该流。希望这能回答问题。