关于 HTTP/2 RFC 实施的流量控制问题

Flow Control questions about HTTP/2 RFC Implementation

我正在构建一个 http/2 客户端,我对 rfc 以及我应该如何处理实现有疑问,尤其是在流量控制方面。

我知道流量控制使用基于信用的 window 大小系统,但我有点不确定如何处理耗尽 window 的情况。

  1. 我是否只是无限期地阻塞,直到 WINDOW_UPDATE 框架释放一切?或者合理的超时时间是多少?

  2. 当 window 耗尽时,我是否暂停发送所有帧? RFC 声明流中帧的顺序对于 headers 和数据帧尤其重要,但它没有明确声明在 window 耗尽时所有帧都应暂停。这对我来说有点模棱两可,因为数据帧是唯一计入 window 大小的数据帧。那么我应该阻止发送所有帧还是只发送 headers/data?对于连接流控制上下文和流流控制上下文,这个答案是否不同?

连接中的所有数据帧都有一个流量控制window,然后每个流都有一个。

1.- 如果连接 window 耗尽,您将暂停发送任何流的数据帧,直到收到 WINDOWS_UPDATE。您可以实施超时。如果超时到期,您唯一的补救办法是关闭连接并重试。

2.- 如果流连接 window 耗尽,则仅暂停该流。

在所有情况下,您只暂停数据帧。其他类型的帧不受流量控制的影响。

如果您实现的是客户端而不是服务器,您更关心的是自己发送 WINDOW_UPDATE 帧。除非你正在做很多 POST 和 PUT,即将数据发送到服务器。

根据我作为 HTTP/2 server 开发人员的经验,我发现在我称为 "trains" 的组中管理 HTTP/2 帧很方便。对于除 HEADERS、PUSH_PROMISE 和 CONTINUATION 之外的所有帧,火车仅由帧组成。对于 HEADERS 和 PUSH_PROMISE,一个序列由该帧和任何后续的 CONTINUATION 帧组成。然后你把你的火车放在以下级别的优先级 queue(第一个具有最高优先级):

  1. PING 帧:您希望对等方准确确定延迟,因此您在收到这些帧后尽快处理它们并尽快发送应答。
  2. 设置,WINDOW_UPDATE,RST_STREAM,GO_AWAY
  3. PUSH_PROMISE 和 HEADERS 火车。 HTTP/2 规范允许两种(实际上是三种)类型的 HEADERS 帧:作为 HTTP headers 本身和尾部发送的帧。这里我说第一个。
  4. 数据帧。如果您正在实施优先级排序,您可能需要在此处进一步确定帧的优先级。

只要通道可用于发送,您就会发送优先级最高的列车 queue。