跳到主要内容

RPC 与代码生成

快速上手​

增加或修改 RPC、协议、Excel 和数据库表时,从开发快速上手选择对应任务。 现有声明负责生成代码,常规扩展不需要编写模板。下文供修改生成行为时查阅。

定制与详细设计​

协议即源头​

业务 RPC 和数据协议以 protobuf 定义。共享框架协议位于 src/server_frame/protocol/, 服务和组件另有自己的 protocol/;atgateway 客户端线协议使用 FlatBuffers。

protocol/
├── private/protocol/ # 仅服务端内部
│ ├── pbdesc/ # svr.protocol.proto(RouterService/LogicCommonService)、svr.*.table.proto(DB 表)
│ ├── common/ config/ extension/ log/
└── public/protocol/ # 可与客户端共享
├── extension/atframework.proto # 自定义 service/rpc 选项(驱动代码生成)
└── pbdesc/ com.protocol*.proto(CS/SS 消息)、com.struct*.proto(数据结构)

生成物一律重新生成,不手工编辑(*.atfw.gen.{h,cpp}、*.pb.{h,cc}、config/db 代码)。

自定义选项(atframework.proto)​

驱动生成的扩展选项分布在三个文件:

  • public/protocol/extension/atframework.proto:atframework.service_options(module_name 等)与 atframework.rpc_options(api_name、allow_no_wait 等);
  • protocol/extension/xrescode_extensions_v3.proto:xrescode.loader 选项,标记 Excel 配置加载器;
  • private/protocol/extension/svr.database.extension.proto:DB 表/索引扩展(KV/KL/CAS/TTL),供 db 模板使用。

生成流水线​

  • src/server_frame/generate_proto_source.cmake / generate_proto_utility.cmake:protoc 编译;
  • src/tools/generate-for-pb/mako-generator.py:读取 pb 描述集,按各 CMakeLists 中声明的规则 (服务名 + 模板 + 输出路径)批量渲染;
  • src/tools/generate_for_pb_utility.cmake:CMake 侧的模板调用封装。

模板清单(src/templates/)​

模板生成物
handle_ss_rpc.*.makoSS RPC 注册函数 register_handles_for_<service>(生成于 app/ 入口目录,服务声明按 MAIN_DIRECTORIES 归入 MAIN_SOURCES/MAIN_HEADERS,编译进服务可执行文件而非私有静态库)
task_action_ss_rpc.*.mako每个 SS RPC 方法的服务端 task action 骨架
rpc_call_api_for_ss.*.makoSS RPC 客户端调用 API(unary/stream/no-wait/broadcast/metadata/user/router 变体)与 per-RPC 全名接口
handle_cs_rpc.*.mako / task_action_cs_rpc.*.mako客户端 RPC 的 handler 与 task action
session_downstream_api_for_cs.*.mako服务器→客户端 session 下行推送 API 与 per-RPC 全名接口
package_request_api_for_simulator.*.makorobot/模拟器用的 CS 请求打包 API
task_action_no_msg.*.mako无消息任务 Action(配合 src/generate-nomsg-task.sh)
db_interface.*.mako / db_rpc_redis(.kv/.kl).*.makoRedis 数据库访问层(rpc/db/local_db_interface.atfw.gen.*)
config_manager.*.mako / config_set.*.mako / config_easy_api.*.makoExcel 配置加载框架与便捷读取 API

orbit 组件另有专用模板:src/component/orbit/sdk/server/template/(同样生成 per-RPC 全名接口)。

SS 模板为每个 RPC 在 packer 子命名空间中生成 gsl::string_view get_full_name_of_<rpc>()(与 pack_<rpc>/unpack_<rpc> 一致,声明在 <service>.atfw.gen.h),返回线上 wire 全名(包.服务/方法)。CS 模板同理在 packer 子命名空间中生成。 orbit fork 模板同样在 packer 子命名空间中生成,返回其点分协议名。 向 test.ss() 注册 mock、断言调用历史等需要 RPC 全名的场景应使用 SS/CS 模板的该接口而非硬编码字符串(见 RPC 单元测试);orbit fork 的 getter 返回点分全名,且 orbit RPC 经 orbit transport 不走 SS 引擎,不可用于 test.ss()。

RPC 调用端 API 形态​

需要回包的 RPC 使用 RPC_AWAIT_CODE_RESULT 或 RPC_AWAIT_TYPE_RESULT 等待完成并取得结果; 不关注回包或返回值时也要用 RPC_AWAIT_IGNORE_RESULT 显式等待并忽略结果。 这些宏统一适配 C++20 协程和传统有栈协程,用法见等待 RPC 完成。

对非 router RPC,stream 或 allow_no_wait 会生成 rpc::<module>::oneway::<rpc>():同步发送、可在 task 外调用、直接返回整数发送结果,不等待响应。普通 unary 调用可用 __no_wait 参数显式选择不等待; __wait_later 仍发送需要响应的请求,供调用方稍后等待。broadcast 是独立的 fire-and-forget 形态。

SS 请求或响应声明为 stream 时,例如 channel_event_sync,每次调用发送一条 SSMsg,不建立 gRPC 式的持续 流连接。具体返回类型、目标参数和命名空间以生成头文件为准。

框架调用结果是整数错误码;rpc::result_code_type 包装需要协程等待的结果,不是 HTTP 状态码类型。 系统、atbus、DB 等错误定义在 svr.const.err.proto,客户端业务错误定义在 com.const.proto。 业务响应中的结果字段需另行检查。