节点js" response.on(' data',func(chunk))"保证块边界

时间:2018-02-28 00:57:28

标签: node.js chunked-encoding

我正在尝试实现我的节点js服务以使用http流(transfer-encoding:chunked)来发回响应。

我使用" response.on(' data',func(chunk))"接收从服务发回的每个块,它现在正在工作。

我的问题是," response.on(' data',func(chunk))"保证回调中的块与服务发送的块完全相同? (或者它可以组合多个服务发送的块并仅调用一次回调,或者将单个服务发送的块拆分成多个并多次调用回调?)

由于 迈克尔

1 个答案:

答案 0 :(得分:0)

  

我的问题是,“response.on('data',func(chunk))”是否保证回调中的块与服务发送的块完全相同?

没有。 Streams对块边界没有任何保证。边界可以在任何地方。

  

或者它可以组合多个服务发送的块并仅调用一次回调

是的,可能。

  

或将单个服务发送块分成多个部分并多次调用回调

是的,可能。

如果您必须处理通常不适合流的离散数据片段(例如特定的数据块),那么您需要在流中创建描述,以告诉您要处理的块的开始位置并且停止以便您可以读取和缓冲块,直到到达块的末尾然后处理整个块,即使块跨越两个或更多实际data事件。

有许多不同的方法来描述流中的特定数据块,以及使用哪种技术完全取决于数据类型。最简单的描述示例是描述文本文件中的行的CRLF。还有很多其他方法可以做到这一点。例如,在二进制工作中,您可以流式传输包含内容长度的标头,该内容长度可以准确地告诉您在块结束之前预期有多少字节。 MIME创建描述部分的唯一字符串标记。根据数据的具体情况,有很多不同的方法可以做到。

仅供参考,如果数据的编写者(在流的另一端)写入一大块数据,然后暂停一段时间(足够长以使块通过网络物理发送),然后写入另一个块然后再次暂停数据,然后收件人可能会立即将每个块组合在一起。但是,这绝不是保证,不应该被依赖。传输中的任何扰动都可能导致延迟或重传,最终可能会混合来自单独发送的块的数据,从而在给定的data事件中将接收到多个块。类似地,如果发送的数据变大或者路径中存在传输打嗝或其他网络基础结构导致数据被分成更小的部分,则可以在多个data事件中接收单个数据块。 / p>

如果您需要在处理之前收集特定的数据块,那么您需要拥有自己的代码,在数据到达时将该块组装到缓冲区中,并在您拥有整个块时识别并处理该块。该代码需要处理所有这些情况:

  1. 一个块到达多个data个事件
  2. 一个data事件包含多个块或多个块的一部分
  3. data事件中到达的边界与块的边界不同(例如,您的块被分成多个data事件,下一个data事件可能包含你的块的结尾和下一个块的开始。)
  4. 仅供参考,创建自己的流子类通常很有用,它可以自动处理数据中的边界,然后在数据完全形成“块”时发出自己的消息。它通常必须使用内部缓冲区和边界检测才能实现。

    例如,有许多模块实现了逐行读取文本流。它们缓冲来自data事件的数据,将其拆分为整行(保留最后一行的额外部分,可能不是整行),然后为每个到达行发出自己的line事件。

    您可能希望为自己的块数据类型执行类似操作。然后,这将允许您以更简单的方式使用派生流,它将仅发出整个块,并且您编写的代码使用该对象将更加简单,因为您将集中块检测逻辑,以便代码的其余部分不必担心。