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

Go使用gRPC流式接口传stream到Chan后发送报transport is closing错误

问题原因与解决方案

核心结论

将stream传入Channel本身不会导致stream或底层连接关闭,该操作仅传递了stream的引用,不会触发gRPC框架的资源回收逻辑。

报错根因

gRPC服务端流式RPC的处理方法Recognize的生命周期与对应stream完全绑定:只要Recognize方法执行结束返回,gRPC框架会自动关闭该stream关联的所有资源,包括底层传输链路。
你的代码中将stream传入Channel后直接return nil,相当于刚把请求抛给后台goroutine,stream就被框架主动回收了,等后台goroutine调用Send时,链路已经关闭,自然抛出transport is closing错误。
你不使用Channel时直接在Recognize方法内执行Send逻辑,方法未返回时stream保持存活,因此可以正常发送。

代码中存在的其他问题

  • 不需要传递stream的指针:AsrService_RecognizeServer本身是接口类型,接口变量传递的就是底层实现的引用,直接赋值即可,不需要取地址后再解引用,多余操作反而容易引入问题。
  • 存在类型不匹配笔误:你定义的接收Chan是ClientRequest类型,实际发送的是ASRRequest类型,需要统一Chan的类型定义。
  • 没有生命周期同步机制:原逻辑没有任何机制阻塞Recognize方法等待后台处理完成,直接返回导致资源提前释放。

修复方案

1. 扩展请求结构体新增同步通道

type ASRRequest struct {
    stream AsrService_RecognizeServer
    done   chan error // 用于传递处理结果,通知原方法可以返回
}
// 统一Chan定义,注意类型匹配
var ASRRequestChan = make(chan *ASRRequest, 200)

2. 修改Recognize方法,阻塞等待处理完成再返回

func (s *ScheduleServer) Recognize(stream AsrService_RecognizeServer) error {
    req, err := stream.Recv()
    if err == io.EOF || err != nil {
        return err
    }
    asrRequest := &ASRRequest{
        stream: stream,
        done:   make(chan error, 1),
    }
    ASRRequestChan <- asrRequest
    // 阻塞等待后台处理完成,不要提前返回
    return <-asrRequest.done
}

3. 修改后台处理逻辑,处理完成后通知原方法

func HandlRequestChan() {
    for r := range ASRRequestChan {
        Log.Infof("Chan get request info[%v]", r)
        var rsp RecognizeResponse
        rsp.Code = 0 // 替换为你的业务逻辑赋值
        err := r.stream.Send(&rsp)
        if err != nil {
            fmt.Printf("Grpc write failed,err[%v]", err)
        }
        fmt.Printf("return time[%v]\n", time.Now().UnixNano()/1e6)
        // 通知原方法处理完成,可以返回
        r.done <- err
        close(r.done)
    }
}

额外注意事项

gRPC的ServerStream不是并发安全的,不要在多个goroutine中同时调用同一个stream的Send或Recv方法,如有并发操作需求需要加锁保护。

内容的提问来源于stack exchange,提问作者Yongqi Z

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 17:36:03