如何直接从protobuf创建GRPC客户端而不将其编译成java代码

2024-04-03

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

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

那么,有没有办法可以跳过这一步呢?

如何创建一个通用的 gRPC 客户端,可以直接从 protobuf 文件调用服务器,而无需编译成 java 代码? 或者,有没有办法在运行时生成代码?

Flow expect: protobuf file -> gRPC client.

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

非常感谢。


Protobuf 系统确实需要 protoc 才能运行。但是,可以跳过生成的代码。而不是传递类似的东西--java_out and --grpc_java_out到协议你可以通过--descriptor_set_out=FILE这将解析.proto文件到一个描述符文件。描述符文件是一个原始编码FileDescriptorSet https://github.com/protocolbuffers/protobuf/blob/3be9322e28dfcacdb669f646f76fe833fa274107/src/google/protobuf/descriptor.proto#L57。这与反射服务使用的基本格式相同。

一旦有了描述符,您就可以一次加载一个 FileDescriptor https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/Descriptors.FileDescriptor.html#buildFrom-com.google.protobuf.DescriptorProtos.FileDescriptorProto-com.google.protobuf.Descriptors.FileDescriptor:A- and 创建动态消息 https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/DynamicMessage.html#getDefaultInstance-com.google.protobuf.Descriptors.Descriptor-.

然后对于 gRPC 部分,您需要创建一个 gRPC MethodDescriptor。

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

static MethodDescriptor.MethodType getMethodTypeFromDesc(
  Descriptors.MethodDescriptor methodDesc
) {
  if (!methodDesc.isServerStreaming()
    && !methodDesc.isClientStreaming()) {
    return MethodDescriptor.MethodType.UNARY;
  } else if (methodDesc.isServerStreaming()
        && !methodDesc.isClientStreaming()) {
    return MethodDescriptor.MethodType.SERVER_STREAMING;
  } else if (!methodDesc.isServerStreaming()) {
    return MethodDescriptor.MethodType.CLIENT_STREAMING);
  } else {
    return MethodDescriptor.MethodType.BIDI_STREAMING);
  }
}

那时你已经拥有了你需要的一切并且可以打电话Channel.newCall(method, CallOptions.DEFAULT) https://grpc.github.io/grpc-java/javadoc/io/grpc/Channel.html#newCall-io.grpc.MethodDescriptor-io.grpc.CallOptions-在 gRPC 中。您也可以免费使用ClientCalls https://grpc.github.io/grpc-java/javadoc/io/grpc/stub/ClientCalls.html使用与存根 API 更相似的东西。

所以动态调用绝对是可能的,并且用于诸如grpcurl https://github.com/fullstorydev/grpcurl。但这也并不容易,因此通常只在必要时才进行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何直接从protobuf创建GRPC客户端而不将其编译成java代码 的相关文章

随机推荐

  • “此哈希方法尚未发现冲突”是什么意思?

    我的意思是我不需要寻找实际的碰撞 就知道它们的存在 如果没有冲突 那么如何获得固定长度的结果呢 这就是为什么我不明白人们声称 md5 不安全 是什么意思 有人发现了碰撞 或者类似的东西 我唯一能想到的是 碰撞搜索仅查找字典单词 例如 如果
  • 如何知道已保存模型中的输出和输入张量名称

    我知道如何加载已保存的 TensorFlow 模型 但如何知道输入和输出张量名称 我可以使用 tf import graph def 加载 protobuf 文件 然后使用函数 get tensor by name 加载张量 但我如何知道任
  • 如何在 CLion 中运行 SFML,错误未定义引用?

    我是 C 新手 尝试学习游戏编程 我选择 SFML 并在 Jetbrain 的 CLion 上运行并使用 Ubuntu 机器 我按照这个教程SFML 和 Linux http sfml dev org tutorials 2 0 start
  • Primefaces 嵌套对话框/'appendToBody' - 支持 bean 操作未触发

    我在两个嵌套表单中有一个支持 bean 方法 会话范围 该方法不会触发 我用一个展示问题的通用示例提出了这个问题 我希望了解如何 为何使用表单 对话框和appendToBody标签导致了问题 为了澄清 该行动contentsOfDialog
  • 如何阻止 Eclipse 每次重新启动时累积 Tomcat 实例?

    我在 Eclipse 2019 3 中运行 Tomcat 8 5 每次我通过单击绿色圆圈 三角形按钮重新启动 Tomcat 实例时 最终都会运行重复的实例 我怎样才能阻止这种情况发生 这是我已经尝试过的一些事情 我尝试升级到tomcat 9
  • PostgreSQL 9.3:将一列拆分为多列

    我想拆分一列colb在下面给出的示例中分为两列 喜欢column1 and column2 我有一个包含两列的表 Example create table t3 cola varchar colb varchar 插入 insert int
  • 在 Angular 中动态设置样式

    我有以下标记 tr style background color none tr 正如它所说 如果activity status字段待定 然后将背景颜色设置为红色 否则设置为绿色 但这不起作用 检查后我发现它呈现如下 tr style ba
  • C# - 编写 COM 服务器 - 映射到方法的属性

    我们正在尝试替换最初为 VB6 应用程序编写的 COM 服务器 我们无法访问源代码 由于某种原因 VB6 应用程序可以调用我们的构造函数 但随后它会得到 系统错误 H80004002 没有这样的 接口支持 我假设当它尝试使用 QueryIn
  • Magento - 致命错误:类名必须是有效的对象或字符串

    我在安装 Magento 时遇到问题 希望有人能帮助我解决 当我访问该网站时 我突然开始收到以下错误消息 Fatal error Class name must be a valid object or a string in app co
  • 科学记数法中的小“e”/Matlab中的Double是什么

    当我计算一个非常小的数字时 matlab给出 1 12345e 15这是什么 我可以将其解释为 1 12345 10 15 或其 1 12345 e 15 我很着急 抱歉问了这个愚蠢的问题 e 代表指数 它的科学计数法 http en wi
  • Crontab 格式化 - 每 15 分钟一次

    我试图让一个简单的 crontab 作业每 15 分钟运行一次 但在决定如何格式化计时时遇到困难 我一直在写的内容如下 15 我很确定这只运行每小时的前 15 分钟 我认为 crontab 允许用户指定确切的运行时间 即 0 15 30 4
  • 从主题读取后立即异步提交消息

    我正在尝试在阅读主题后立即提交一条消息 我已点击此链接 https www confluence io blog apache kafka spring boot application https www confluent io blo
  • 如何在drawString Java中更改字体大小

    如何让字体变大g drawString Hello World 10 10 g setFont new Font TimesRoman Font PLAIN fontSize 其中 fontSize 是一个 int 这绘制字符串的API h
  • 异步运行一些 Python 代码的正确方法是什么?

    我需要从我的普通 Flask 应用程序发送邮件 所以我认为最简单的方法是使用 smtplib 发送邮件 但我必须异步执行 你不能只在请求中插入 3 秒的延迟 对吧 因此 我将电子邮件添加到队列 psql 表 中 并从读取该表并使用 smpt
  • 如何在 R 中创建具有特定 MA(或 q)项的 ARIMA 模型

    我无法确定使用 arima stats 创建 ARMA 模型的特定方法 该模型具有特定的 MA 项 而这些项不仅仅由最大数指定 我的意思是 我需要指定一个 AR 1 MA 1 4 模型 该模型应该产生截距 AR1 项 MA1 项和 MA4
  • 将视频保存到 CameraRoll React-Native

    可以使用cameraRoll在React Native上保存视频 对于使用saveImageWithTag 的图像 这很容易 但我找不到视频文档 将视频保存到相机胶卷非常容易 我使用以下代码行完成了它 saveVideoToCameraRo
  • 对数据框中的列中的数据进行分类

    我的数据框中有一列数字 我想将这些数字分类为例如高 低 排除 我该如何做到这一点 我一无所知 我尝试查看剪切函数和类别数据类型 一个简短的例子pd cut 让我们从一些数据框开始 df pd DataFrame A 0 8 2 5 9 15
  • 点击 wkwebview 链接时不会打开

    我正在开发一个应用程序 其中一些代码继承自其他开发人员 并具有加载 html 文件的 Web 视图 html 文件中包含电话号码和网页链接 如果长按电话号码将会打开 但 html 链接不会打开 我希望它们通过短按打开 但短按什么也没有发生
  • 从其他进程向 WPF 单例应用程序发送数据

    我有一个 WPF 单例应用程序 其中任何时候只有一个实例在运行 如果用户尝试启动另一个实例 我们检查它是否已经在运行 然后我们终止这个新进程并将现有进程置于前面 现在 我们需要从另一个进程 可以是 xls word 或另一个独立应用程序 打
  • 如何直接从protobuf创建GRPC客户端而不将其编译成java代码

    使用 gRPC 时 我们需要通过协议缓冲区编译器 protoc 或使用 Gradle 或 Maven protoc 构建插件从 proto 服务定义生成 gRPC 客户端和服务器接口 Flow now protobuf file gt ja