如果在响应返回之前取消一个gRPC调用中的上下文。客户端的错误代码可能是CANCEL和mapping to RST_STREAM,则此RST_STREAM将被发送到服务器。RST_STREAM帧允许立即终止流,即当前RPC调用流将被终止。但是,HTTP2连接仍然存在。当调用下一个RPC调用时,将使用另一个新流来进行RPC调用。 下面是一些测试代码片段。 客户端:100毫秒后强制取消上下文。
conn, err := grpc.Dial(serverAddr,
grpc.WithTransportCredentials(insecure.NewCredentials()))
defer conn.Close()
c := pb.NewGreeterClient(conn)
for i := 0; i < 10; i++ {
ctx, cancel := context.WithCancel(context.TODO())
go func() {
// force call cancel after 100 milliseconds
time.Sleep(100 * time.Millisecond)
cancel()
}()
r, err := c.SayHello(ctx, &pb.HelloRequest{Name: "name"})
}
服务器端:在1秒内延迟sayHello响应。
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
// Delay ack on server by 1 seconds
randMS := 1000
select {
case <-time.After(time.Duration(randMS) * time.Millisecond):
case <-ctx.Done():
if ctx.Err() == context.Canceled || ctx.Err() == context.DeadlineExceeded {
log.Printf("SayHello: context err %+v \n", ctx.Err())
return nil, ctx.Err()
}
}
2条答案
按热度按时间8i9zcol21#
默认情况下,
HTTP2
用作gPRC的底层协议。HTTP2
连接上可能有多个流。下图说明了HTTP2
从web dev的连接和流如果在响应返回之前取消一个gRPC调用中的上下文。客户端的错误代码可能是
CANCEL
和mapping toRST_STREAM
,则此RST_STREAM
将被发送到服务器。RST_STREAM
帧允许立即终止流,即当前RPC调用流将被终止。但是,HTTP2
连接仍然存在。当调用下一个RPC调用时,将使用另一个新流来进行RPC调用。下面是一些测试代码片段。
客户端:100毫秒后强制取消上下文。
服务器端:在1秒内延迟sayHello响应。
使用
GODEBUG=http2debug=2
运行代码,更多gRPC的调试日志可以帮助我们了解客户端和服务器之间的消息。客户端日志
inb24sb22#
假设一个客户端取消了它的上下文,这是否会导致一个新的HTTP请求发送到服务器,通知服务器先前/正在进行的GRPC请求的上下文被取消了?
否。它会关闭网络连接。
服务器如何知道客户端是否取消了上下文?
由于网络连接被关闭的事实。