The spec说:
新建立的流的标识符必须是数字的 大于启动端点已打开的所有流或 保留。这将控制使用HEADERS框架打开的流 和使用PUSH_PROMISE保留的流。一个端点 收到意外的流标识符必须用a响应 PROTOCOL_ERROR类型的连接错误(第5.4.1节)。
对于发送PUSH_PROMISE
的服务器的情况,我认为符合要求的服务器必须发送严格增加的流ID。但我不明白客户端应该如何检测这种情况。
例如,在一个连接上,如果服务器发送:
PUSH_PROMISE
承诺的第2流PUSH_PROMISE
承诺的第4流因为并发,客户端可能会收到
PUSH_PROMISE
承诺的第4流PUSH_PROMISE
承诺的第2流规范会让我觉得客户端应该对此产生错误,但服务器没有做错任何事。
我在这里缺少什么?
答案 0 :(得分:3)
如果服务器写了PUSH_PROMISE[stream=2]
然后PUSH_PROMISE[stream=4]
,那么这些帧将以相同的顺序传送(这由TCP保证)。
客户端的任务是以有序的方式从套接字读取。 对于HTTP / 2实现,要求甚至更严格,因为它不仅必须以有序的方式从套接字读取,而且还必须以有序的方式解析帧。
这是PUSH_PROMISE
帧携带HPACK块并且为了使服务器和客户端HPACK上下文保持同步这一事实所必需的,必须处理帧(或至少这些帧的HPACK块)按顺序排列,stream=2
之前 stream=4
。
之后,客户端可以同时处理2帧。
对于实现,这实际上非常简单,因为分配用于执行I / O读取的线程通常会:
loop
read bytes from socket
if no bytes or socket closed -> break loop
parse read bytes (with HPACK decoding) -> produce frame objects
pass frame objects to upper software layer
end loop
由于read和parse是顺序的,并且没有其他线程从同一个套接字读取,因此符合订购保证。