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

如何在不依赖Grpc.Core.Api的前提下使用gRPC IServerStreamWriter

免责声明:该问题可能纯粹属于设计审美层面的考量。

实现方案

完全不需要传递IServerStreamWriter类型,也不用做消息拷贝适配,只要在Actor核心层定义最小抽象、gRPC层做薄适配即可,全程几乎无额外性能开销,也不会破坏Actor层无外部依赖的设计原则。

具体落地步骤:

  • 首先在无任何外部依赖的Actor核心模块内,定义业务需要的流写入抽象接口,不要带任何gRPC相关的命名或类型引用:
// 归属Actor核心模块,零外部依赖
public interface IBusinessStreamWriter<in TMsg>
{
    Task WriteAsync(TMsg message, CancellationToken ct = default);
}
  • 之后在依赖Grpc.Core.Api的gRPC转换层,做一个极薄的适配器实现,直接转发方法调用,不做任何数据转换、拷贝操作:
// 归属gRPC服务层,仅该层需要引用gRPC相关依赖
internal sealed class GrpcStreamWriterAdapter<TMsg> : IBusinessStreamWriter<TMsg>
{
    private readonly IServerStreamWriter<TMsg> _rawGrpcWriter;

    public GrpcStreamWriterAdapter(IServerStreamWriter<TMsg> rawGrpcWriter)
    {
        _rawGrpcWriter = rawGrpcWriter;
    }

    public Task WriteAsync(TMsg message, CancellationToken ct = default)
        => _rawGrpcWriter.WriteAsync(message);
}
  • 最后gRPC服务层收到流请求时,把原生的IServerStreamWriter包装成上面的适配器实例,随转换后的Actor消息传给对应Actor即可。Actor全程只依赖核心层自定义的IBusinessStreamWriter接口,完全感知不到gRPC类型的存在,写入操作是直接转发到原生gRPC写入方法,没有任何序列化、数据拷贝的额外开销,仅多了一次接口方法调用,性能损耗可以忽略。
扩展说明
  • 后续如果要支持其他带服务端流的通信协议(比如WebSocket、私有TCP协议),只需要在对应协议的转换层实现IBusinessStreamWriter的适配逻辑即可,Actor侧的核心业务逻辑不需要做任何改动,完全符合最初的架构隔离目标。
  • 如果业务需要感知流关闭、流报错等生命周期事件,只需要在核心层的IBusinessStreamWriter接口上追加对应方法定义,再在各协议适配层做对应转发即可,不会破坏依赖边界。
  • 不要为了所谓的“纯”Actor设计去做消息拷贝,这类跨层适配用接口隔离是行业通用做法,不存在设计层面的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 08:42:13