Go RPC能否传输chan类型?为何返回的Message.Done字段为nil
问题结论
chan类型确实不支持通过Go标准库net/rpc进行跨端传输,你观察到的Done字段为nil是符合预期的行为,不是代码逻辑错误。
原因说明
- 标准库
net/rpc默认使用encoding/gob作为序列化编码格式,gob的编码规则明确不支持chan(通道)、func(函数)两类类型的序列化:编码阶段遇到结构体里的这两类字段会直接跳过,不会写入序列化字节流,客户端反序列化时对应字段会被初始化为类型零值,而chan的零值就是nil。 - 从设计本质上看,chan是Go运行时实现的单进程内内存通信机制:它它绑定了当前进程的内存空间、运行时调度状态、协程阻塞队列等进程独有的上下文,本身就不具备跨进程/跨网络传输的可能。哪怕强行把服务端chan的内存地址传到客户端,客户端进程里这个地址指向的内存也不是合法的通道对象,完全无法工作。
实践建议
跨端RPC场景不要尝试传递chan类型:
- 如果只是需要传递事件状态,可以在结构体里用基础类型的状态字段标识事件完成情况;
- 如果需要实现类似服务端主动通知的异步效果,可以用双向流式RPC、长连接消息推送,或者封装专门的阻塞式RPC方法供客户端调用等待,代替直接持有服务端的chan实例。
内容的提问来源于stack exchange,提问作者youngzy
相关产品推荐
相关产品推荐

