协议缓冲区如何直接从protobuf创建GRPC客户端,而无需将其编译为java代码
当使用GRPC时,我们需要从我们的。通过协议缓冲区编译器(protoc)或使用Gradle或Maven protoc构建插件定义proto服务
Flow now: protobuf file -> java code -> gRPC client.
那么,有没有办法跳过这一步
如何创建一个通用的GRPC客户机,它可以直接从protobuf文件调用服务器,而无需编译成java代码? 或者,有没有办法在运行时生成代码
Flow expect: protobuf file -> gRPC client.
我想建立一个通用的gRPC客户端系统,输入是protobuf文件以及方法、包、消息请求的描述。。。无需为每个protobuf重新编译
多谢各位
# 1 楼答案
Protobuf系统确实需要运行protoc。但是,可以跳过生成的代码。您可以传递} 。这与反射服务使用的基本格式相同
--descriptor_set_out=FILE
将.proto
文件解析为描述符文件,而不是将--java_out
和--grpc_java_out
之类的内容传递给protoc。描述符文件是proto-encoded ^{一旦有了描述符,就可以load it a FileDescriptor at a time和create a DynamicMessage
然后,对于gRPC片段,您需要创建一个gRPC MethodDescriptor
在这一点上,您就拥有了所需的一切,并且可以在gRPC中调用^{} 。您还可以自由地使用^{} 来使用更类似于存根API的东西
所以动态调用是绝对可能的,并且用于grpcurl之类的事情。但这也不容易,因此通常只有在必要时才进行
# 2 楼答案
从技术上讲,两者都是可能的
codegen只是生成了几个类;主要是protobuf消息、grpc方法描述符和存根。您可以实现它或签入生成的代码以绕过codegen。我不确定做这个tbh有什么好处。而且,如果原版被更改,这将是非常烦人的
只要您签入一些接口/抽象类来表示生成的存根/方法描述符和protobuf消息,就可以使用byte-codegen动态地执行此操作。您必须确保这些非动态代码与proto定义同步(最有可能是运行时检查/异常)
# 3 楼答案
从技术上讲,没有什么可以防止这种情况发生。两大障碍是:
两者都是可能的,但都不是微不足道的
对于1,粗略的方法是使用描述符集选项shell/invoke
protoc
生成模式二进制文件,然后将其反序列化为FileDescriptorSet
(从descriptor.proto);此模型允许您访问protoc
如何查看文件。一些平台还具有本机解析器(本质上是将protoc
重新实现为该平台中的库),例如protobuf-net.Reflection在中这样做。净地对于2,here's an implementation of that in C#。即使细节有所不同,这种方法也应该可以相当方便地移植到Java中。您可以查看生成的实现,以了解它在任何特定语言中的工作方式
(很抱歉,具体的例子是C#/.NET,但我就住在那里;方法应该是可移植的,即使具体的代码:不是直接的)
# 4 楼答案
我是用Java做的,步骤是:
FileDescriptorProto
列表FileDescriptorProto
列表中获取方法的FileDescriptor
ServiceDescriptor
获取MethodDescriptor
,从FileDescriptor
获取MethodDescriptor
生成MethodDescriptor<DynamicMessage, DynamicMessage>
DynamicMessage
DynamicMessage
响应解析为JSON您可以在项目helloworlde/grpc-java-sample#reflection中引用完整的示例
原型是:
您自己启动该proto的服务器,并使用Java编写完整代码,如下所示: