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.*.mako | SS 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.*.mako | SS 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.*.mako | robot/模拟器用的 CS 请求打包 API |
task_action_no_msg.*.mako | 无消息任务 Action(配合 src/generate-nomsg-task.sh) |
db_interface.*.mako / db_rpc_redis(.kv/.kl).*.mako | Redis 数据库访问层(rpc/db/local_db_interface.atfw.gen.*) |
config_manager.*.mako / config_set.*.mako / config_easy_api.*.mako | Excel 配置加载框架与便捷读取 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。
业务响应中的结果字段需另行检查。