【问题标题】:How could I send message of many fields with c++ grpc stream?如何使用 c++ grpc 流发送多个字段的消息?
【发布时间】:2020-03-05 05:28:55
【问题描述】:

假设我需要从服务器发送到客户端的消息是这样的:

message BatchReply {
    bytes data = 1;
    repeated int32 shape = 2;
    string dtype = 3;
    repeated int64 labels = 4;
}

这里shape/dtype只是小变量,可以用几个int空间来表示,而data/labels是大内存缓冲区,最多可以占用1G内存。

我正在尝试使用流发送此消息:

service ImageService {
    rpc get_batch (BatchRequest) returns (stream BatchReply) {}
}

我的问题是,我可以找到通过流发送消息的示例都是关于消息结构中只有一个字段的消息,例如:

service TransferFile {
    rpc Upload(stream Chunk) returns (Reply) {}
}
message Chunk {
    bytes buffer = 1; // here is only on field of buffer, what if there is a field of int val = 2; ?
}

如果Chunk 的结构中有两个字段怎么办。在同一个流送过程中,每次调用set_buffer()时,是否需要调用set_val()

【问题讨论】:

    标签: c++ stream protocol-buffers grpc


    【解决方案1】:

    您可以通过 grpc 发送包含多个字段的消息。这就是使用 protobuf 的优势。

    我不知道您使用的传输层是否能够处理您指定的这么大的消息。你可以测试一下。如果这不起作用,您可以使用您提供的TransferFile 示例。

    查看Chunk 时,我觉得他们正在发送整个数据的片段。另一方面,他们然后将这些片段重建为完整的集合。 Chunk 使用的类型是字节。这些只是原始字节,可以表示您想要的任何内容。

    要分块发送您的BatchReply,您可以使用以下步骤:

    1. BatchReply 对象中设置数据。
    2. 将对象序列化为字节数组。
    3. Chunk 对象中设置一个字节数组块。例如每次 100 个字节。
    4. 使用TransferFile接口发送Chunk对象。
    5. 从第 3 步开始重复该过程。直到到达字节数组的末尾。

    在接收端,您将块连接成一个数组并将该数组反序列化回BatchReply 对象。

    【讨论】:

    • 感谢您的回复,以确保我明白您的想法:首先我将数据添加到 BatchReply,然后我使用 protobuf api 将它们序列化,然后我将序列化的结构作为字节添加到 @987654331 @ 并通过流发送。最后,我在客户端收到它,然后将其反序列化为原始结构并解析它,对吗?
    • 顺便说一句,你推荐我使用流或一元调用来传输序列化数据吗?
    • 是的,就是这个过程。但前提是您不能一次性发送 BatchReply。我没有足够的关于流的知识来判断流或一元调用。
    猜你喜欢
    • 1970-01-01
    • 2013-01-08
    • 2018-05-29
    • 1970-01-01
    • 1970-01-01
    • 2018-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多