6

So, recently I learned about how to do streaming with protobuf-net.grpc with the help of IAsyncEnumerable<T>. 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."). 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).

Sooo, how do I do this then?

Sossenbinder
  • 4,852
  • 5
  • 35
  • 78

1 Answers1

6

There are two separate concepts here:

  • gRPC allows a stream of messages via IAsyncEnumerable<T> (instead of a Task<T> for a single message)
  • 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.

If you need to provide a stream and additional metadata a few options exist:

  • use http headers (via CallContext as a second parameter)
  • 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
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900