我想使用gRPC进行传输,将文件从客户端传输到服务器,并将文件从服务器传输到客户端。但是,接收过程不知道期望多少字节。我看到了一些建议,将其附加在要传输的数据的开头,然后在从流中接收到第一个块时将其解析出来。但是,如果可能,我想避免这种情况。在gRPC C ++ API中,我看到ClientWriter实现了ClientStreamingInterface并可以使用WaitForInitialMetadata()访问服务器元数据。服务器实现ServerStreamingInterface,并且可以使用SendInitialMetadata()方法发送服务器metadat。
从the documentation开始,不清楚该元数据由什么组成,以及我如何添加自己的元数据,以便在发送之前可以通知客户端服务器期望的文件大小。
此外,我发现没有简单的方法可以使用gRPC C ++ API向服务器通知客户端期望的文件大小。
当然,我是gRPC和C ++的新手,因此向正确方向的任何指针将不胜感激。
这里有一个参考:https://grpc.github.io/grpc/cpp/classgrpc__impl_1_1_client_context.htmlhttps://grpc.github.io/grpc/cpp/classgrpc__impl_1_1_server_context.html
还有一个例子:https://github.com/grpc/grpc/blob/master/examples/cpp/metadata/greeter_server.cc
客户端和服务器都可以指定初始元数据,分别在ClientContext和ServerContext上发送。该方法在ClientContext上称为AddMetadata,在ServerContext上称为AddInitialMetadata(以区别于尾随的元数据):
// AddMetadata (const grpc::string &meta_key, const grpc::string &meta_value)
context->AddMetadata("custom-server-metadata", "initial metadata value");
在这种情况下,值是一个字符串。要指定一个数字,通常会使用grpc :: to_string:
context->AddInitialMetadata("filesize", grpc::to_string(file_size));
接收方的元数据格式为
const std::multimap< grpc::string_ref, grpc::string_ref > &
此类型由ServerContext :: client_metadata()(在服务器端获取客户端的初始元数据)和ClientContext :: GetServerInitialMetadata()(在服务器中返回WaitForInitialMetadata()后返回服务器的初始元数据)返回。同步API或其他API中的等效API。
要查找文件大小,可以执行以下操作:
int filesize = atoi(metadata.find("filesize")->second);
((如果不确定是否指定了“ filesize”,则可能要检查metadata.find(“ filesize”)!= metadata.end())
关于如何发送初始元数据,当您在网上发送RPC时,它会自动在客户端发送。在服务器端,您可以使用SendInitialMetadata()显式发送它,也可以将其与您的第一个服务器一起发送到流中。