简体   繁体   English

如何在 protobuf-net.grpc 的消息中使用 IAsyncEnumerable?

[英]How to use IAsyncEnumerable within a message in protobuf-net.grpc?

So, recently I learned about how to do streaming with protobuf-net.grpc with the help of IAsyncEnumerable<T> .所以,最近我在IAsyncEnumerable<T>的帮助下了解了如何使用 protobuf-net.grpc 进行流式传输。 This all works fine and dandy, but I'm facing a bit of an issue right now.这一切都很好,很花哨,但我现在面临一些问题。

For some of my calls, I'd like to call with both some metadata as well as the stream as parameter.对于我的一些调用,我想使用一些元数据和流作为参数进行调用。

For example:例如:

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

With the following signature:带有以下签名:

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

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

However, when trying to call this, I'm getting an exception like 'Status(StatusCode=Unimplemented, Detail="Method is unimplemented.") .但是,当尝试调用它时,我收到了一个异常,如'Status(StatusCode=Unimplemented, Detail="Method is unimplemented.") I know that status responses are a bit cryptic, so I figured out that this is actually just an issue with the parameter.我知道状态响应有点神秘,所以我发现这实际上只是参数的问题。

How do I do this then?那我该怎么做呢?

I also tried to do it with the following signature:我还尝试使用以下签名来做到这一点:

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

With the same outcome, as I'm apparently only allowed to provide a single parameter (True to the grpc definition of one message parameter and one response output).具有相同的结果,因为我显然只允许提供一个参数(对于一个消息参数和一个响应输出的 grpc 定义是正确的)。

Sooo, how do I do this then? Sooo,那我该怎么做呢?

There are two separate concepts here:这里有两个独立的概念:

  • gRPC allows a stream of messages via IAsyncEnumerable<T> (instead of a Task<T> for a single message) gRPC 允许通过IAsyncEnumerable<T>的消息流(而不是单个消息的Task<T>
  • however, each individual message must be complete and self contained;但是,每个单独的消息都必须是完整且独立的; the marshaller (per-message serializer) is synchronous only编组器(每消息序列化器)仅同步

So: you can use IAsyncEnunerable<T> as the parameter or return of a service method, but not as a field on a message.所以:您可以将IAsyncEnunerable<T>用作服务方法的参数或返回,但不能用作消息中的字段。

If you need to provide a stream and additional metadata a few options exist:如果您需要提供流和其他元数据,则存在一些选项:

  • use http headers (via CallContext as a second parameter)使用 http 标头(通过CallContext作为第二个参数)
  • have two service calls - one that initiates things and gets the metadata, one that returns the stream有两个服务调用 - 一个启动事物并获取元数据,一个返回流
  • have a stream with some optional fields in the message, and only populate the optional fields in the first or last message在消息中有一个包含一些可选字段的流,并且只填充第一条或最后一条消息中的可选字段

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM