如何在 protobuf-net.grpc 的消息中使用 IAsyncEnumerable?
How to use IAsyncEnumerable within a message in protobuf-net.grpc?
所以,最近我在 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 定义的一个消息参数和一个响应输出)。
太好了,那我该怎么做?
这里有两个不同的概念:
- gRPC 允许通过
IAsyncEnumerable<T>
的消息流(而不是单个消息的 Task<T>
)
- 但是,每条消息都必须完整且独立;编组器(per-message 序列化程序)仅同步
因此:您可以将 IAsyncEnunerable<T>
用作服务方法的参数或 return,但不能用作消息的字段。
如果您需要提供流和额外的元数据,有几个选项:
- 使用 http headers(通过
CallContext
作为第二个参数)
- 有两个服务调用 - 一个启动事物并获取元数据,一个 return流
- 在消息中有一个包含一些可选字段的流,并且只填充第一条或最后一条消息中的可选字段
所以,最近我在 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 定义的一个消息参数和一个响应输出)。
太好了,那我该怎么做?
这里有两个不同的概念:
- gRPC 允许通过
IAsyncEnumerable<T>
的消息流(而不是单个消息的Task<T>
) - 但是,每条消息都必须完整且独立;编组器(per-message 序列化程序)仅同步
因此:您可以将 IAsyncEnunerable<T>
用作服务方法的参数或 return,但不能用作消息的字段。
如果您需要提供流和额外的元数据,有几个选项:
- 使用 http headers(通过
CallContext
作为第二个参数) - 有两个服务调用 - 一个启动事物并获取元数据,一个 return流
- 在消息中有一个包含一些可选字段的流,并且只填充第一条或最后一条消息中的可选字段