gRPC 服务器端半关闭是否应该隐式终止客户端?
Should gRPC server-side half-closing implicitly terminate the client?
在http2-spec中,服务器半关闭流的场景(服务器发送http2.END_STREAM),客户端仍然允许发送数据(因为它是半关闭的)。
考虑以下 gRPC 场景:
- 客户端向服务器打开bidi-stream并开始发送数据
- 服务器关闭响应流并发送状态预告片(转换为发送 http2.END_STREAM)
- 客户端继续发送数据
gRPC 中的语义定义是否明确?
可能的方式:
- 遵循http2规范:允许客户端继续发送服务器处理过的数据。
- 不遵循 http2 规范:如果服务器关闭流,客户端连接将隐式终止。
注意:我刚刚测试过 Java 的 gRPC 似乎遵循变体 "not follow the http2-spec",即如果服务器关闭向下流,向上流也会关闭。
在gRPC的语义中,当服务器发送一个状态时,就意味着整个调用完成了。官方服务器实现除了 END_STREAM
之外还发送 RST_STREAM
以在 HTTP/2 协议级别关闭双向流,符合 Section 8.1 of the HTTP/2 RFC 的这一部分:
A server can send a complete response prior to the client sending an entire request if the response does not depend on any portion of the request that has not been sent and received. When this is true, a server MAY request that the client abort transmission of a request without error by sending a RST_STREAM
with an error code of NO_ERROR
after sending a complete response (i.e., a frame with the END_STREAM
flag).
当服务器不这样做时,gRPC协议不禁止客户端在收到状态后发送更多数据,但服务器不会处理它,因此没有理由这样做。因此,当官方 gRPC 客户端收到状态时,他们认为调用已完成并停止发送数据。
在http2-spec中,服务器半关闭流的场景(服务器发送http2.END_STREAM),客户端仍然允许发送数据(因为它是半关闭的)。
考虑以下 gRPC 场景:
- 客户端向服务器打开bidi-stream并开始发送数据
- 服务器关闭响应流并发送状态预告片(转换为发送 http2.END_STREAM)
- 客户端继续发送数据
gRPC 中的语义定义是否明确?
可能的方式:
- 遵循http2规范:允许客户端继续发送服务器处理过的数据。
- 不遵循 http2 规范:如果服务器关闭流,客户端连接将隐式终止。
注意:我刚刚测试过 Java 的 gRPC 似乎遵循变体 "not follow the http2-spec",即如果服务器关闭向下流,向上流也会关闭。
在gRPC的语义中,当服务器发送一个状态时,就意味着整个调用完成了。官方服务器实现除了 END_STREAM
之外还发送 RST_STREAM
以在 HTTP/2 协议级别关闭双向流,符合 Section 8.1 of the HTTP/2 RFC 的这一部分:
A server can send a complete response prior to the client sending an entire request if the response does not depend on any portion of the request that has not been sent and received. When this is true, a server MAY request that the client abort transmission of a request without error by sending a
RST_STREAM
with an error code ofNO_ERROR
after sending a complete response (i.e., a frame with theEND_STREAM
flag).
当服务器不这样做时,gRPC协议不禁止客户端在收到状态后发送更多数据,但服务器不会处理它,因此没有理由这样做。因此,当官方 gRPC 客户端收到状态时,他们认为调用已完成并停止发送数据。