http2 中的 half close 有啥作用? http2中流状态的本地和远程之间的区别是啥?
Posted
技术标签:
【中文标题】http2 中的 half close 有啥作用? http2中流状态的本地和远程之间的区别是啥?【英文标题】:What the half close does in http2? What the diff between local and remote in stream state in http2?http2 中的 half close 有什么作用? http2中流状态的本地和远程之间的区别是什么? 【发布时间】:2019-01-19 18:18:48 【问题描述】:http2 中的 half close 有什么作用? http2中流状态的本地和远程有什么区别?
我已经看到:reserved(local) --> half closed(remote)
在流的生命周期中。
为什么本地到远程?为什么不reserved(local) --> half closed(local)
?
【问题讨论】:
【参考方案1】:每个流都有两个不同的观点——客户端和服务器,请求者和提供者。随心所欲。
因此,当发送 PUSH_PROMISE 时使用“保留”状态。此时服务器已声明它打算将资源推送到另一个流上,因此流标识符被保留,不能用于除此推送资源之外的任何东西。
此时服务器看到如下:
它将是一个服务器启动的流,因此将是一个偶数流。 服务器自己保留了流 id - 它没有被远程客户端保留。因此reserved (local)
然后它将发送 HEADERS 帧响应。此时服务器已经开始发送资源,所以当这种情况发生时,HTTP/2 基本上说从客户端的角度来看流是关闭的——它是为了监听传入的数据,而不是发送任何数据(除了像 WINDOWS_UPDATE 这样的控制信号、PRIORITY 或 RST_STREAM 帧)。流现在实际上是单向或半关闭,并且它对发送任何数据的远程客户端关闭,但仍然允许本地服务器发送数据 - 因此half closed (remote)
客户将从相反的角度看到完全相同的流程:
它从 PUSH_PROMISE 获知一个流已被保留,它应该期待它很快到来。 由于流是服务器启动的流,它不是客户端创建的流,因此它被视为远程保留流 - 因此reserved (remote)
在服务器开始发送数据后,客户端知道它不允许在该流上发送任何数据(并不是说它确实是用于 Push Promise 流,但仍然如此)。它可以重新确定推送资源的优先级(使用 PRIORITY 帧)甚至取消它(使用 RST_STREAM 帧),但这就是它所能做的(除了使用 WINDOWS_UPDATE 帧确认接收数据)。因此,流受限于客户端可以在其上发送的内容 - 或者规范更喜欢说它对于任何客户端(又名本地)请求是半关闭 - 因此half-closed (local)
。李>
理解HTTP/2 state model 的关键是要认识到请求不会沿着一侧或另一侧向下流动——而是同时沿着两侧向下流动!这仅取决于您是从发送方还是接收方的角度看待它。
【讨论】:
你的解释太好了!!太感谢了!!我还有一个问题,为什么 PUSH_PROMISE 只是一个标题?在 rfc 中,PUSH_PROMISE frame (with implied CONTINUATIONs)
,这意味着通过发送 PUSH_PROMISE ,数据/内容也应该被发送?但似乎数据/内容是通过发送 Header 而不是 PP 发送的?
感谢您的夸奖!如果您喜欢我的回答风格并想了解更多关于 HTTP/2 的信息,请查看我的书:manning.com/books/…
一定会看看你的书!
一个 PUSH_PROMISE 不是被推送的资源。这是一个虚拟请求,旨在充当对该资源的传入 HEADERS 请求,如果它正常进入而不是由服务器推送,则看起来像这样。所以正常的请求是:HEADERS(发送),HEADERS(接收),DATA(接收)。一个推送的资源是:PUSH_PROMISE(收到)、HEADERS(收到)、DATA(收到)。由于只能推送 GET 请求,因此没有带有 PUSH_PROMISE 的正文。需要 PUSH_PROMISE 帧来警告客户端即将有传入请求以及将打开的流 id。
明白!非常感谢您提供的详细信息!以上是关于http2 中的 half close 有啥作用? http2中流状态的本地和远程之间的区别是啥?的主要内容,如果未能解决你的问题,请参考以下文章
scikit-learn 中的“fit”方法有啥作用? [关闭]
Websocket、Server Sent Events (SSE) 和 HTTP2 的 Server Pushing 有啥区别?