接收方应该以什么频率WINDOW_UPDATE
发送帧?我已经测试了 HTTP/2 客户端,它与 HTTP/2 服务器建立了 HTTP/2,并进行了 Magic、SETTNGS 帧(64K 窗口大小)交换。现在客户端无法向服务器发送超过 64K 大小的数据。
2 回答
接收方应该以什么频率发送 WINDOW_UPDATE 帧?
在接收器决定的任何频率。您不必确认每条消息,但也不应等到整个窗口用完。
例如,Nghttp(一个流行的 HTTP/2 库、服务器和客户端)在 50% 的窗口已用完时发送它:
int nghttp2_should_send_window_update(int32_t local_window_size,
int32_t recv_window_size) {
return recv_window_size > 0 && recv_window_size >= local_window_size / 2;
}
我已经测试了 HTTP/2 客户端,它与 HTTP/2 服务器建立了 HTTP/2,并进行了 Magic、SETTNGS 帧(64K 窗口大小)交换。现在客户端无法向服务器发送超过 64K 大小的数据。
如果服务器没有发送 WINDOWS_UPDATE 帧以允许客户端发送更多数据,我并不感到惊讶。这就是 WINDOWS_UPDATE 框架的意义——避免淹没无法跟上的一方。但是,由接收方(在这种情况下为服务器)发送 WINDOWS_UPDATE 帧以告诉客户端它能够发送更多。因此,如果您只使用 HTTP/2 客户端进行测试,则这不在您的控制范围内。
根据HTTP2规范,需要发送 WINDOW_UPDATE 帧来调整您的发送窗口。这里描述了初始状态:
首次建立 HTTP/2 连接时,将创建初始流控制窗口大小为 65,535 个八位字节的新流。连接流控制窗口也是 65,535 个八位字节。两个端点都可以通过在构成连接前言的一部分的 SETTINGS 帧中包含 SETTINGS_INITIAL_WINDOW_SIZE 的值来调整新流的初始窗口大小。只能使用 WINDOW_UPDATE 帧更改连接流控制窗口。
根据我对规范的阅读,您需要在耗尽窗口缓冲区的任何时候发送 WINDOOW_UPDATE 。这在一个示例中描述如下:
例如,如果客户端在连接建立时立即发送 60 KB 并且服务器将初始窗口大小设置为 16 KB,则客户端将在收到 SETTINGS 帧时重新计算可用的流控制窗口为 -44 KB。客户端保留一个负流控制窗口,直到 WINDOW_UPDATE 帧将窗口恢复为正,之后客户端可以继续发送。
因此,作为发送方,您需要随时调整窗口缓冲区大小,否则会耗尽窗口缓冲区。您需要跟踪发送的数据量和当前窗口缓冲区大小,并相应地发送 WINDOW_UPDATE。