You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

gRPC客户端流创建是否为异步?双向流调用为何不阻塞等待服务端处理

问题原因

你对gRPC流RPC的调用行为理解有误,gRPC中**一元RPC(普通的请求-响应模式)**的客户端调用确实是同步阻塞的,会等服务端完整处理请求返回响应后才返回。但不管是客户端流、服务端流还是双向流,流RPC的客户端调用都不会阻塞等待服务端业务逻辑执行完成:

  • 你调用client1.Stream(ctx)的时候,gRPC客户端底层只完成了HTTP/2流的创建、请求头的发送,只要和服务端的流链路建立成功,就会立刻返回流对象sc1,不会等你服务端侧的Stream处理函数执行到把客户端加入广播列表的业务逻辑。
  • 此时服务端的Stream处理函数可能还在执行校验、初始化逻辑,还没把当前客户端注册到广播池,你立刻启动client2登录,自然会出现client1收不到广播的情况。

解决方案

要确保服务端已经完成client1的流注册逻辑再执行client2登录,有两种常用的实现方案:

方案1:业务层增加流就绪确认(推荐)

在服务端的Stream处理函数中,完成流注册逻辑后,主动给客户端发送一条流就绪的通知事件,客户端收到该事件后再执行后续逻辑:

  1. 先在proto的StreamResponse中新增就绪事件类型:
message StreamResponse {
    oneof event {
        ClientLogin client_login = 1;
        // 新增流就绪事件
        StreamReady stream_ready = 2;
    }
}
message StreamReady {}
  1. 服务端Stream处理函数补充发送就绪通知的逻辑:
func (s *ChatServiceImpl) Stream(stream ChatService_StreamServer) error {
    // 原有逻辑:校验token、初始化流上下文
    // ...
    // 完成流注册,加入广播列表
    s.mu.Lock()
    s.onlineStreams = append(s.onlineStreams, stream)
    s.mu.Unlock()

    // 新增:发送流就绪通知
    if err := stream.Send(&StreamResponse{
        Event: &StreamResponse_StreamReady{},
    }); err != nil {
        return err
    }

    // 原有后续流处理逻辑
    // ...
}
  1. 测试代码补充等待就绪的逻辑:
// step 3: 启动接收协程
readyc := make(chan struct{}) // 新增就绪通知通道
go func() {
    // 先接收就绪通知
    readyRes, err := sc1.Recv()
    if err != nil {
        t.Fatalf("接收流就绪通知失败: %v", err)
    }
    if _, ok := readyRes.Event.(*StreamResponse_StreamReady); ok {
        close(readyc)
    }

    // 原有处理登录广播的逻辑
    res, _ := sc1.Recv()
    t.Logf("got a response from client1 %+v", res)
    m := res.Event.(*StreamResponse_ClientLogin)
    if m.ClientLogin.Name == "test2" {
        loginSuccess = true
    }
    close(waitc)
}()

// 新增:等待流完全就绪再登录client2
<-readyc

// step 4: 创建client2登录
client2 := NewChatServiceClient(conn)
// ... 原有后续逻辑

方案2:测试侧临时加短时间等待(不推荐)

如果不想修改业务代码,也可以在调用Stream之后加100~500ms的睡眠,但这种方式不稳定,不同环境下可能还是会出现时序问题,仅适合临时调试用。

内容的提问来源于stack exchange,提问作者tmp dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 00:24:06