0

在 http2-spec 中,服务器半关闭流的场景(服务器发送 http2.END_STREAM),仍然允许客户端发送数据(因为它是半关闭的)。

考虑以下 gRPC 场景:

  • 客户端打开双向流到服务器并开始发送数据
  • 服务器关闭响应流并发送状态预告片(转换为发送 http2.END_STREAM)
  • 客户端继续发送数据

gRPC 中的语义定义是否明确?

可能的方式:

  • 遵循http2-spec:允许客户端继续发送由服务器处理的数据。
  • 不遵循 http2-spec:如果服务器关闭流,客户端连接将被隐式终止。

注意:我刚刚测试过,它看起来像 Java 的 gRPC 遵循变体“不遵循 http2-spec”,即如果服务器关闭向下的流,则向上的流也被关闭。

4

1 回答 1

2

在 gRPC 的语义中,当服务器发送一个状态时,就意味着整个调用完成。根据HTTP/2 RFC 第 8.1 节的这一部分,官方服务器实现RST_STREAM除了END_STREAM在 HTTP/2 协议级别关闭双向流之外还发送:

如果响应不依赖于尚未发送和接收的请求的任何部分,则服务器可以在客户端发送整个请求之前发送完整的响应。当这是真的时,服务器可以通过在发送完整响应(即带有标志的帧)之后发送RST_STREAM带有错误代码的错误代码来请求客户端中止请求的传输而不会出现错误。NO_ERROREND_STREAM

当服务器不这样做时,gRPC 协议不会禁止客户端在收到状态后发送更多数据,但服务器不会处理它,因此没有理由这样做。因此,当官方 gRPC 客户端收到状态时,他们认为调用已完成并停止发送数据。

于 2019-04-04T17:58:29.717 回答