news 2026/9/12 2:00:26

FlatBuffers 与 gRPC 集成指南:构建、测试与 C++ Callback API 代码生成

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FlatBuffers 与 gRPC 集成指南:构建、测试与 C++ Callback API 代码生成

FlatBuffers 与 gRPC 集成指南:构建、测试与 C++ Callback API 代码生成

【免费下载链接】flatbuffersFlatBuffers: Memory Efficient Serialization Library项目地址: https://gitcode.com/GitHub_Trending/fl/flatbuffers

本篇技术指南以 grpc/README.md 为核心,系统讲解在 FlatBuffers 仓库中如何构建并运行 gRPC 集成测试,以及如何通过flatc生成基于现代 gRPC Callback API 的 C++ 服务端与客户端代码。读完本文,你将掌握 Linux 环境下 gRPC + FlatBuffers 的完整构建流程、Bazel 替代方案、测试运行方式,以及四种 RPC 流式形态(Unary / Client streaming / Server streaming / Bidi streaming)对应的 reactor 返回类型与async_*客户端方法签名。

gRPC 支持在 FlatBuffers 仓库中的组织方式

FlatBuffers 仓库中的grpc/目录承载了与 gRPC 相关的全部内容,整体布局如下:

  • grpc/src/compiler/:与 gRPC 项目共享的代码生成器源码,按语言拆分为 cpp_generator.cc、go_generator.cc、java_generator.cc、python_generator.cc、swift_generator.cc、ts_generator.cc 等,配合 schema_interface.h 提供统一的 schema 访问抽象;
  • grpc/tests/:gRPC 专属测试(如 grpctest.cpp 以及回调 API 的编译期测试);
  • grpc/examples/:Go、Python、Swift、TypeScript 四种语言的 greeter 示例,schema 见 greeter.fbs;
  • grpc/samples/greeter/:C++ 版 greeter 示例(client.cpp / server.cpp);
  • grpc/flatbuffers-java-grpc/:Java 侧 gRPC 工具类。

文档强调了一个重要约定:grpc/src/下的文件与 gRPC 项目共享,并在 gRPC 仓库中维护,任何改动都应提交到 gRPC 项目而非 FlatBuffers 仓库。这些文件是从 gRPC 拷贝而来,同时服务于 Protobuf 与 FlatBuffers 两套代码生成器——这从 cpp_generator.h 的注释可以得到印证:“cpp_generator.h/.cc 不直接依赖 gRPC/ProtoBuf,因此可以被用于为其他序列化系统(如 FlatBuffers)生成代码”。

grpc/tests/中存放的是 gRPC 专属测试。要编译这些测试,必须先构建并安装 gRPC 库,然后通过主 FlatBuffers CMake 工程的FLATBUFFERS_BUILD_GRPCTEST选项开启编译。

在 Linux 上构建带 gRPC 的 FlatBuffers

前置准备:下载并安装 gRPC

  1. 下载、构建并安装 gRPC(可参考 gRPC 官方 C++ 安装指引,例如克隆 gRPC 仓库)。
  2. 假设你的 gRPC 克隆位于/your/path/to/grpc_repo
  3. 使用自定义安装目录安装 gRPC:
    make install prefix=/your/path/to/grpc_repo/install

配置环境变量

构建 gRPC 测试需要两个环境变量,它们分别告诉 CMake gRPC 的安装位置与 Protobuf 源码位置:

export GRPC_INSTALL_PATH=/your/path/to/grpc_repo/install export PROTOBUF_DOWNLOAD_PATH=/your/path/to/grpc_repo/third_party/protobuf

配置并编译

mkdir build ; cd build cmake -DFLATBUFFERS_BUILD_GRPCTEST=ON -DGRPC_INSTALL_PATH=${GRPC_INSTALL_PATH} -DPROTOBUF_DOWNLOAD_PATH=${PROTOBUF_DOWNLOAD_PATH} .. make

这三个 CMake 变量在主 CMakeLists.txt 中有严格校验:FLATBUFFERS_BUILD_GRPCTEST默认为 OFF(第 27 行定义),当开启后,若未定义GRPC_INSTALL_PATHPROTOBUF_DOWNLOAD_PATH,CMake 会直接报错并提示“See grpc/README.md”。校验通过后,CMake 会将${GRPC_INSTALL_PATH}/include${PROTOBUF_DOWNLOAD_PATH}/src加入 include 搜索路径,并把${GRPC_INSTALL_PATH}追加进CMAKE_PREFIX_PATH以帮助查找 gRPC 库。

Bazel 用户

如果你使用 Bazel 构建,可直接运行:

bazel test src/compiler/...

该命令会验证grpc/src/compiler/下的各语言生成器(BUILD 定义见 grpc/src/compiler/BUILD.bazel)。

运行 FlatBuffers gRPC 测试

Linux

先让动态链接器找到 gRPC 的共享库,再运行测试:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${GRPC_INSTALL_PATH}/lib make test ARGS=-V

ARGS=-V会以 verbose 模式输出每个测试用例的详细结果。

以 grpctest.cpp 为例,该测试覆盖了典型的 gRPC 集成场景:

  • 服务端派生自生成的MonsterStorage::Service,实现 Unary RPCStore(用fbb_.ReleaseMessage<Stat>()MessageBuilder构建的响应所有权移交给 gRPC)与 Server streaming RPCRetrieve(通过writer->Write(monster)循环发送 5 条消息);
  • 客户端通过grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials())连接,并分别用MessageBuilder与普通FlatBufferBuilder各执行一次StoreRPCRetrieveRPC
  • FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION未定义时,还会构造一个无效请求,断言 RPC 返回StatusCode::INTERNAL且错误消息为 “Message verification failed”,验证 gRPC 消息自动校验机制。

Bazel 用户

bazel test tests/...

C++ Callback API 代码生成

生成命令

FlatBuffers 的 gRPC C++ 代码生成目前可选支持现代 gRPC Callback API。在现有Service与异步 mixin 之外,同时生成CallbackService骨架的方式是让flatc同时携带--grpc--grpc-callback-api两个选项:

flatc --cpp --grpc --grpc-callback-api your_service.fbs

从源码看,flatc解析到该选项后,会在 idl_gen_grpc.cpp 中将其写入generator_parameters.generate_callback_api,最终传递给 gRPC 侧的生成器——对应 cpp_generator.h 中Parameters结构体的bool generate_callback_api = false字段(默认关闭,显式开启才生成)。

生成的 CallbackService

开启该选项后,生成的头文件会在宏保护下新增一个类(原文档示例):

class YourService::CallbackService : public ::grpc::Service { /* reactor virtuals */ };

该类的实际生成逻辑位于 cpp_generator.cc:先输出#if defined(GRPC_CALLBACK_API_NONEXPERIMENTAL)保护宏,再打印CallbackService的前向声明与类定义,并声明每个 RPC 对应的 reactor 虚函数;末尾以#endif // GRPC_CALLBACK_API_NONEXPERIMENTAL收尾,保证旧版 gRPC 库下不产生破坏性变更。

每种 RPC 形态映射到相应的 reactor 返回类型:

RPC 形态CallbackService 方法返回类型
Unary::grpc::ServerUnaryReactor*
Client streaming::grpc::ServerReadReactor<Request>*
Server streaming::grpc::ServerWriteReactor<Response>*
Bidi streaming::grpc::ServerBidiReactor<Request, Response>*

默认生成的方法实现返回nullptr,需要在你的派生类中覆写并返回一个由你管理的 reactor 实例(生命周期模式参考 gRPC 官方文档)。若你的 gRPC 库早于稳定版回调 API 宏(即不存在GRPC_CALLBACK_API_NONEXPERIMENTAL),保护宏内的代码会被整体跳过,不影响原有编译。使用该特性请确保构建基于较新的 gRPC(1.38+,具体最低版本以 gRPC 仓库为准)。

仓库中提供了对应的编译期验证测试:grpctest_callback_compile.cpp 在FLATBUFFERS_GENERATED_GRPC_CALLBACK_APIGRPC_CALLBACK_API_NONEXPERIMENTAL同时定义时,派生一个CallbackServiceImpl : public MyGame::Example::MonsterStorage::CallbackService并实例化,用于确认生成的服务端骨架可编译(仅编译验证,不执行任何 RPC)。

客户端 Callback Stubs

当提供--grpc-callback-api时,生成的 C++ 客户端 stub 会在原有的同步 / 通用异步风格之外,新增基于原生回调 / reactor 的异步方法,并由同一个宏保护。对每个名为Foo的 RPC,生成的方法签名如下(摘自原文档):

Unary:

void async_Foo(::grpc::ClientContext*, const Request&, Response*, std::function<void(::grpc::Status)>); void async_Foo(::grpc::ClientContext*, const Request&, Response*, ::grpc::ClientUnaryReactor*);

Client streaming:

::grpc::ClientWriteReactor<Request>* async_Foo(::grpc::ClientContext*, Response*, ::grpc::ClientWriteReactor<Request>*);

Server streaming:

::grpc::ClientReadReactor<Response>* async_Foo(::grpc::ClientContext*, const Request&, ::grpc::ClientReadReactor<Response>*);

Bidirectional streaming:

::grpc::ClientBidiReactor<Request, Response>* async_Foo(::grpc::ClientContext*, ::grpc::ClientBidiReactor<Request, Response>*);

这些方法直接映射到原生 gRPC 回调 API 工厂(如CallbackUnaryCallClientCallbackWriterFactory::Create等),不会自行创建线程,I/O 驱动需要按 gRPC 文档覆写相应的 reactor 回调。若构建使用的 gRPC 缺少非实验性宏,这些符号将不会被生成,从而保持向后兼容。

客户端侧的编译期验证见 grpctest_callback_client_compile.cpp:它通过static_assert检查Stub::async_Store(Unary 的函数形式与 reactor 形式)、Stub::async_Retrieve(Server streaming 的ClientReadReactor)、Stub::async_GetMaxHitPoint(Client streaming 的ClientWriteReactor)以及Stub::async_GetMinMaxHitPoints(Bidi 的ClientBidiReactor)等成员函数指针是否存在,属于纯编译期测试,不发起实际 RPC。

多语言示例与常见注意事项

grpc/examples/下的 greeter 示例展示了同一种 schema 在多种语言中的落地方式:

  • grpc/examples/go/greeter:Go 客户端与服务端;
  • grpc/examples/python/greeter:Python 客户端与服务端;
  • grpc/examples/swift/Greeter:Swift 实现;
  • grpc/examples/ts/greeter:TypeScript 实现;
  • grpc/samples/greeter:C++ 版(含 Makefile)。

示例 schema 定义了一个典型的rpc_service(见 grpc/examples/greeter.fbs):

namespace models; table HelloReply { message:string; } table HelloRequest { name:string; } rpc_service Greeter { SayHello(HelloRequest):HelloReply; SayManyHellos(HelloRequest):HelloReply (streaming: "server"); }

grpc/examples/README.md 记录了两种语言的已知问题,值得在实际开发中留意:

  • Python:由于 Python 端可能收到Bytes arrayutf8 string,服务端 / 客户端需要自行断言类型。例如在SayHello中应先通过HelloRequest.HelloRequest().GetRootAs(request, 0)解析,再对字符串做reply.decode('UTF-8')编码处理;更稳妥的做法是保证所有进出 Python 的请求都是Bytes array,如hello_request = bytes(builder.Output())
  • Go:payload 的content-type必须设置为application/grpc+flatbuffers,例如.SayHello(ctx, b, grpc.CallContentSubtype("flatbuffers"))

小结

围绕 grpc/README.md,本文完整覆盖了 FlatBuffers 与 gRPC 集成的三个层面:构建(CMake 的FLATBUFFERS_BUILD_GRPCTEST与两个路径变量,或 Bazel 的bazel test)、测试运行(make test ARGS=-VLD_LIBRARY_PATH),以及--grpc-callback-api带来的现代 C++ 回调式代码生成。其中 Callback API 部分既有生成代码的形态说明(四种 RPC 映射的 reactor 类型、客户端四种async_*签名),也有仓库中两份编译期测试作为落地验证。配合多语言 greeter 示例与已知问题清单,你可以据此快速搭建基于 FlatBuffers 序列化的 gRPC 服务。

【免费下载链接】flatbuffersFlatBuffers: Memory Efficient Serialization Library项目地址: https://gitcode.com/GitHub_Trending/fl/flatbuffers

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 1:55:39

基于YOLOV5的面部情感表情检测实践指南

简介&#xff1a;基于YOLOV5的面部情感表情检测识别Python源码&#xff0c;面向计算机视觉学习者、人工智能课程设计与毕业设计学生&#xff0c;可用于快速实现人脸表情&#xff08;如喜怒哀乐等&#xff09;的检测与识别。项目包含84个文件&#xff0c;整体体积约1.06MB&#…

作者头像 李华
网站建设 2026/9/12 1:51:48

Debian环境变量配置与管理全指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 1:50:11

MATLAB贝叶斯优化LSTM时间序列预测系统

简介&#xff1a;本资源是一份面向MATLAB初学者与时间序列建模进阶学习者的完整实践方案&#xff0c;聚焦贝叶斯优化与LSTM协同建模这一前沿技术组合&#xff0c;解决金融、电力、气象等领域的高精度时序预测问题。压缩包共5个文件&#xff0c;含2个说明类txt文档&#xff08;含…

作者头像 李华