如何直接从protobuf创建GRPC客户端而不将其编译为Java代码 [英] How to create GRPC client directly from protobuf without compiling it into java code

查看:140
本文介绍了如何直接从protobuf创建GRPC客户端而不将其编译为Java代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用GRPC时,我们需要通过协议缓冲区编译器(protoc)或使用Gradle或Maven protoc构建插件从.proto服务定义中生成gRPC客户端和服务器接口.

When working with GRPC, we need to generate the gRPC client and server interfaces from our .proto service definition via protocol buffer compiler (protoc) or using Gradle or Maven protoc build plugin.

Flow now: protobuf file -> java code -> gRPC client.

那么,有什么方法可以跳过这一步吗?

So, is there any way to skip this step?

如何创建一个通用的GRPC客户端,可以直接从protobuf文件中调用服务器而无需编译为Java代码?还是有一种在运行时生成代码的方法?

How to create a generic GRPC client that can call the server directly from the protobuf file without compile into java code? Or, is there a way to Generated Code at runtime?

Flow expect: protobuf file -> gRPC client.

我想用输入的是protobuf文件以及方法,程序包,消息请求的描述来构建通用的gRPC客户端系统,而不必为每个protobuf再次编译.

I want to build a generic gRPC client system with the input are protobuf files along with description of method, package, message request ... without having to compile again for each protobuf.

非常感谢您.

推荐答案

Protobuf系统确实需要运行协议.但是,可以跳过生成的代码.无需传递诸如-java_out -grpc_java_out 之类的协议,您可以传递-descriptor_set_out = FILE 来解析.proto 文件转换为 descriptor 文件.描述符文件是 proto-encoded FileDescriptorSet .这与反射服务使用的基本格式相同.

Protobuf systems really need protoc to be run. However, the generated code could be skipped. Instead of passing something like --java_out and --grpc_java_out to protoc you can pass --descriptor_set_out=FILE which will parse the .proto file into a descriptor file. A descriptor file is a proto-encoded FileDescriptorSet. This is the same basic format as used with the reflection service.

有了描述符后,您可以创建DynamicMessage.

Once you have a descriptor, you can load it a FileDescriptor at a time and create a DynamicMessage.

然后对于gRPC,需要创建一个gRPC MethodDescriptor.

Then for the gRPC piece, you need to create a gRPC MethodDescriptor.

MethodDescriptor.<DynamicMessage, DynamicMessage>newBuilder()
    // UNKNOWN is fine, but the "correct" value can be computed from
    // methodDesc.toProto().getClientStreaming()/getServerStreaming()
    .setType(MethodDescriptor.MethodType.UNKNOWN)
    .setFullMethodName(MethodDescriptor.generateFullMethodName(
        serviceDesc.getFullName(), methodDesc.getName()))
    .setRequestMarshaller(ProtoUtils.marshaller(
        DynamicMessage.newBuilder(methodDesc.getInputType()).buildPartial()))
    .setResponseMarshaller(ProtoUtils.marshaller(
        DynamicMessage.newBuilder(methodDesc.getOutputType()).buildPartial()))
    .build();

到那时,您将拥有所需的一切,并可以调用 ClientCalls 使用与存根API更相似的内容.

At that point you have everything you need and can call Channel.newCall(method, CallOptions.DEFAULT) in gRPC. You're also free to use ClientCalls to use something more similar to the stub APIs.

因此,动态调用绝对是可能的,并且可用于 grpcurl 之类的东西.但这也不容易,因此通常仅在必要时进行.

So dynamic calls are definitely possible, and is used for things like grpcurl. But it also is not easy and so is generally only done when necessary.

这篇关于如何直接从protobuf创建GRPC客户端而不将其编译为Java代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆