前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >grpc 检测客户端连接是否存在

grpc 检测客户端连接是否存在

作者头像
超级大猪
发布2019-11-27 16:47:58
7.3K0
发布2019-11-27 16:47:58
举报
文章被收录于专栏:大猪的笔记

默认情况下,服务端是没有检测客户端连接是否存活的。 如果因为网络抖动,客户端退出,此时客户端会向服务端发送一个Fin_wait2的消息。但这个消息如果丢失,服务端将长期认为客户端“仍然存在”,即使此时客户端已经退出。 为了解决这个问题,grpc服务端在启动的时候,可以传入keepalive参数,原理是:每隔N秒ping客户端,当客户端无法ping通的时候,服务端会主动断开连接。代码如下:

代码语言:javascript
复制
var kasp = keepalive.ServerParameters{
            Time:    5 * time.Second, // Ping the client if it is idle for 5 seconds to ensure the connection is still active
            Timeout: 1 * time.Second, // Wait 1 second for the ping ack before assuming the connection is dead
        }

lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
if err != nil {
    log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer(grpc.KeepaliveParams(kasp))

pb.RegisterHelloServer(s, &svc{})
if err := s.Serve(lis); err != nil {
    log.Fatalf("failed to serve: %v", err)
}

上面的代码表明,每隔5s ping一次客户端,并且回包必须在1s内返回。否则连接将被回收。 服务端的处理代码可以写成这样:

代码语言:javascript
复制
func (s *svc) HelloStream(stream pb.Hello_HelloStreamServer) error {
    now := time.Now().Unix()
    log.Println("enter stream", now)

    req, err := stream.Recv()
    if err != nil {
        return err
    }
    name := req.Greetings

loop:
    for {
        out := new(pb.HelloRsp)
        out.Resp = fmt.Sprintf("hello,%v", name)
        sendctx, sendcancel := context.WithCancel(context.Background())
        go func() {
            err := stream.Send(out) // 在协程中send,使得context.Done响应能被处理
            if err != nil {
                log.Println(err)
            }
            sendcancel()
        }()

        select {
        case <-sendctx.Done():
        case <-stream.Context().Done()://当keepalive连接超时,这里的逻辑被执行,服务端退出
            log.Println("client closed")
            break loop
        }
        time.Sleep(time.Second)
    }
    log.Println("exit stream")
    return nil
}

真的隐蔽啊。真的坑啊。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-11-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档