【问题标题】:How to use IAsyncEnumerable within a message in protobuf-net.grpc?如何在 protobuf-net.grpc 的消息中使用 IAsyncEnumerable?
【发布时间】:2020-02-01 13:58:41
【问题描述】:

所以,最近我在IAsyncEnumerable<T> 的帮助下了解了如何使用 protobuf-net.grpc 进行流式传输。这一切都很好,花花公子,但我现在面临一些问题。

对于我的一些调用,我想使用一些元数据以及流作为参数进行调用。

例如:

[OperationContract]
Task<bool> UploadPicture(ProfilePictureQuery query);

带有以下签名:

[ProtoContract]
public class ProfilePictureQuery
{
    [ProtoMember(1)]
    public IAsyncEnumerable<byte[]> RawDataStream { get; set; }

    [ProtoMember(2)]
    public string FileExtension { get; set; }
}

但是,当我尝试调用它时,我得到了一个像 'Status(StatusCode=Unimplemented, Detail="Method is unimplemented.") 这样的异常。我知道状态响应有点神秘,所以我发现这实际上只是参数的问题。

那我该怎么做呢?

我也尝试使用以下签名:

[OperationContract]
Task<bool> UploadPicture(IAsyncEnumerable<byte[]> rawDataStream, string fileExtension);

同样的结果,因为我显然只被允许提供一个参数(一个消息参数和一个响应输出的 grpc 定义是正确的)。

Sooo,那我该怎么做呢?

【问题讨论】:

    标签: c# grpc protobuf-net


    【解决方案1】:

    这里有两个独立的概念:

    • gRPC 允许通过IAsyncEnumerable&lt;T&gt; 发送消息流(而不是单个消息的Task&lt;T&gt;
    • 但是,每个单独的消息都必须完整且独立;编组器(每消息序列化程序)仅是同步的

    所以:您可以将IAsyncEnunerable&lt;T&gt; 用作服务方法的参数或返回值,但不能用作消息上的字段。

    如果您需要提供流和其他元数据,有几个选项可供选择:

    • 使用http头(通过CallContext作为第二个参数)
    • 有两个服务调用 - 一个启动事物并获取元数据,一个返回流
    • 在消息中有一个带有一些可选字段的流,并且只填充第一条或最后一条消息中的可选字段

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    相关资源
    最近更新 更多