gRPC一元调用服务器连接状态检查

huangapple go评论92阅读模式
英文:

gRPC Unary Call Connection State Check on Server

问题

我有一个一元的 gRPC 调用,在我的 Go gRPC 服务器上可能需要几分钟才能处理(涉及移动应用程序上的人工代理)。我想知道在发送响应之前,是否有一种方法可以检查客户端是否已经终止了连接。

我找到了 ServerStreaming 情况下使用 Context Status.Done 通道的解决方案,但对于我的一元 RPC 来说,它不起作用。

以下是应该进行控制的函数的签名:

func (*Server) EndpointName(ctx context.Context, in *pb.EndpointRequest) (*pb.EndpointResponse, error) {
英文:

I have an unary gRPC call that can take up to few minute to be processed on my Go gRPC server (involves human agent on the mobile APP). I would like to know if there is a way to check if the connection has been terminated on the client side before sending the response.

I found the solution for ServerStreaming case with Context Status.Done channel, but it does not work for my Unary RPC.

Below is the signature of the function where the control should be made:

func (*Server) EndpointName(ctx context.Context, in *pb.EndpointRequest) (*pb.EndpointResponse, error) {

答案1

得分: 2

根据你的问题中显示的函数定义,端点函数接收一个context (ctx context.Context)。如果连接断开,上下文将被取消。

例如,我可以修改helloworld示例,以便模拟一个长时间运行的作业:

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
	select {
	case <-ctx.Done():
		fmt.Println("上下文已完成:", ctx.Err())
		return nil, status.Error(codes.Canceled, "无关紧要,因为任何东西都不会得到这个...")
	case <-time.After(time.Minute):
		// 这里模拟一个长时间运行的过程。实际上,该过程本身应该检查上下文
	}
	return &pb.HelloReply{}, nil
}

为了测试这个,我修改了greeter_client来调用这个函数,并在等待响应时触发panic();服务器输出如下:

2022/08/08 08:16:57 服务器监听在 [::]:50051
上下文已完成:上下文已取消
英文:

As per the function definition shown in your question, the endpoint function is passed a context (ctx context.Context). If the connection drops the context will be cancelled.

For example I can modify the helloworld example so that it simulates a long running job:

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
	select {
	case &lt;-ctx.Done():
		fmt.Println(&quot;Context is done:&quot;, ctx.Err())
		return nil, status.Error(codes.Canceled, &quot;does not matter as nothing will ever get this anyway...&quot;)
	case &lt;-time.After(time.Minute):
		// This simulates a long-running process. In reality the process itself should be checking the context
	}
	return &amp;pb.HelloReply{}, nil
}

To test this I altered greeter_client to call the function and then panic() whilst waiting for the response; the server outputs:

2022/08/08 08:16:57 server listening at [::]:50051
Context is done: context canceled

huangapple
  • 本文由 发表于 2022年8月7日 22:57:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/73268496.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定