我最近一直在玩GRPC
和Protocol Buffers
,以便熟悉C ++中的两个框架。
我想尝试一下反射功能,所以我设置了一个非常简单的服务,其中(支持反射的)服务器公开了以下接口文件:
syntax = "proto3";
package helloworld;
service Server {
rpc Add (AddRequest) returns (AddReply) {}
}
message AddRequest {
int32 arg1 = 1;
int32 arg2 = 2;
}
message AddReply {
int32 sum = 1;
}
在客户端,由于grpc::ProtoReflectionDescriptorDatabase
,我可以看到上一个方法。因此,我可以通过DynamicMessageFactory
创建消息。但是,我还没有能够将消息实际发送到服务器,也没有找到文档中的任何具体细节。也许它太明显了,我完全迷失了......
任何提示都将深表感谢!
using namespace google::protobuf;
void demo()
{
std::shared_ptr<grpc::Channel> channel = grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials());
// Inspect exposed method
grpc::ProtoReflectionDescriptorDatabase reflection_database(channel);
std::vector<std::string> output;
reflection_database.GetServices(&output);
DescriptorPool reflection_database_pool(&reflection_database);
const ServiceDescriptor* service = reflection_database_pool.FindServiceByName(output[0]);
const MethodDescriptor* method = service->method(0);
// Create request message
const Descriptor* input_descriptor = method->input_type();
FileDescriptorProto input_proto;
input_descriptor->file()->CopyTo(&input_proto);
DescriptorPool pool;
const FileDescriptor* input_file_descriptor = pool.BuildFile(input_proto);
const Descriptor* input_message_descriptor = input_file_descriptor->FindMessageTypeByName(input_descriptor->name());
DynamicMessageFactory factory;
Message* request = factory.GetPrototype(input_message_descriptor)->New();
// Fill request message (sum 1 plus 2)
const Reflection* reflection = request->GetReflection();
const FieldDescriptor* field1 = input_descriptor->field(0);
reflection->SetInt32(request, field1, 1);
const FieldDescriptor* field2 = input_descriptor->field(1);
reflection->SetInt32(request, field2, 2);
// Create response message
const Descriptor* output_descriptor = method->output_type();
FileDescriptorProto output_proto;
output_descriptor->file()->CopyTo(&output_proto);
const FileDescriptor* output_file_descriptor = pool.BuildFile(output_proto);
const Descriptor* output_message_descriptor = output_file_descriptor->FindMessageTypeByName(output_descriptor->name());
Message* response = factory.GetPrototype(output_message_descriptor)->New();
// How to create a call...?
// ...is grpc::BlockingUnaryCall the way to proceed?
}
答案 0 :(得分:0)
已经有几年了,但是由于您没有得到答案,所以我会尝试。您也没有使用特定语言标记问题,但看起来您正在使用CPP。我无法为CPP提供解决方案,但可以为JVM语言提供解决方案。
首先,以下内容摘自我正在开发的名为okgrpc的开源库。这是用Java创建动态gRPC客户端/ CLI的第一次尝试。
以下是使用DynamicMessage
拨打电话的一般步骤:
DescriptorProtos.FileDescriptorProto
。Descriptors.MethodDescriptor
。DynamicMessage
。当然,如何执行此操作取决于输入。如果是JSON字符串,则可以使用JsonFormat
类。io.grpc.MethodDescriptor
。您需要编写自己的DynamicMessage
编组器。显然,细节决定成败。如果使用Java,则可以使用我的库,让它成为我的问题。如果使用其他语言,祝您好运。