redis 客户端断开连接_go – 如何在客户端断开连接时正确使用ctx.Done()?

你可以使用select.而不是正常从函数获取数据,使用通道获取数据和go例程来处理它.

有点像这样:

func (a *API) Notifications(in *empty.Empty, stream

pb.Service_NotificationsServer) error {

ctx := stream.Context()

_, ok := user.FromContext(ctx)

if !ok {

return grpc.Errorf(codes.Unauthenticated, "user not found")

}

pubsub := a.redisClient.Subscribe("notifications")

defer pubsub.Close()

// I can not build the code, so I assume the msg in your code Message struct

c := make(chan Message)

go func() {

for {

msg, err := pubsub.ReceiveMessage()

if err != nil {

grpclog.Warningf("Notifications: pubsub error: %v", err)

close(c)

return grpc.Errorf(codes.Internal, "pubsub error %v", err)

}

c

}

}()

for {

select {

case msg, ok :=

if !ok {

// channel is closed handle it

}

notification := &pb.Notification{}

err = json.Unmarshal([]byte(msg.Payload), notification)

if err != nil {

grpclog.Warningf("Notifications: parse error: %v", err)

continue

}

if err := stream.Send(notification); err != nil {

grpclog.Warningf("Notifications: %v", err)

return err

}

grpclog.Infof("Notifications: send msg %v", notification)

case

// do exit logic. some how close the pubsub, so next

// ReceiveMessage() return an error

// if forget to do that the go routine runs for ever

// until the end of main(), which I think its not what you wanted

pubsub.Close() // Its just pseudo code

return

}

}

}

从通道中读取消息(我假设类型为Message),并使用select的电源.

在这种情况下另外两个相关的事情:

>确保完成此功能后,go例程结束.我无法猜测,因为我不知道代码,但我假设有一个Close()方法关闭pubsub所以下一个ReceiveMessage返回错误. (我看到推迟做我希望的工作)>如果在ctx.Done之前ReceiveMessage中存在错误,您可以关闭通道然后中断循环.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值