108 lines
4.5 KiB
Markdown
108 lines
4.5 KiB
Markdown
|
|
# BaseModule
|
|||
|
|
|
|||
|
|
**公共运行时库**:被 `ServerModule` 与 `CrossModule` 依赖。包含 **Netty TCP 帧编解码**、**CmdRpc 分发管线**、**Proto 元数据注册表**、**Spring 命令扫描** 以及与跨服调用相关的 **`CrossRpcInvoker` 接口**。
|
|||
|
|
|
|||
|
|
本模块 **不是** 可执行 Spring Boot 应用;随区服或跨服进程一起加载。
|
|||
|
|
|
|||
|
|
## 网络分层(逻辑)
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
flowchart TB
|
|||
|
|
subgraph TCP["TCP 字节流"]
|
|||
|
|
F["一帧: 4B length + body"]
|
|||
|
|
end
|
|||
|
|
subgraph Net["BaseModule / net & frame"]
|
|||
|
|
D["LengthPrefixedProtobuf 解码"]
|
|||
|
|
H["CmdRpcTcpFrameHandler"]
|
|||
|
|
end
|
|||
|
|
subgraph Cmd["BaseModule / cmd"]
|
|||
|
|
CD["CmdRpcChannelDispatch"]
|
|||
|
|
PR["ProtoRegistry → ProtoInfo"]
|
|||
|
|
PC["ProtoCommandReflect 解析 CTS / newBuilder STC"]
|
|||
|
|
DP["CmdRpcDispatch → GameCommand"]
|
|||
|
|
end
|
|||
|
|
F --> D --> H --> CD
|
|||
|
|
CD --> PR
|
|||
|
|
CD --> PC
|
|||
|
|
CD --> DP
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 1. 帧格式:`LengthPrefixedProtobuf`
|
|||
|
|
|
|||
|
|
- **编码**:`LengthPrefixedProtobuf.encodeMessage(alloc, CmdRpcEnvelope)` — 先写 **大端 int32 长度**,再写 `CmdRpcEnvelope.toByteArray()`。
|
|||
|
|
- **解码**:`newTcpFrameDecoder()` 返回 Netty 解码器,攒满一帧后向 pipeline 下游抛出 **一条 ByteBuf(仅 body)**。
|
|||
|
|
|
|||
|
|
这样 **区服客户端 TCP** 与 **跨服 TCP** 与 **区服连跨服的 Outbound** 三者 **帧格式一致**,仅 IP/端口与 `CommandSource` 不同。
|
|||
|
|
|
|||
|
|
## 2. 入站处理:`CmdRpcTcpFrameHandler`
|
|||
|
|
|
|||
|
|
- 读取一帧 `byte[]`,调用 **`CmdRpcChannelDispatch.dispatch(...)`**。
|
|||
|
|
- 将返回的 **`CmdRpcEnvelope`** 再次 **长度前缀编码** 写回对端。
|
|||
|
|
- `linkSource` 由构造时注入:`Client_TCP`(区服接客户端)或 `CROSS_TCP`(跨服接入站)。
|
|||
|
|
|
|||
|
|
**注意**:默认在 **Netty IO 线程** 上执行命令;若 `roundTrip` 同步调跨服会阻塞该连接上的 IO,Demo 场景可接受,生产需评估线程模型。
|
|||
|
|
|
|||
|
|
## 3. 分发核心:`CmdRpcChannelDispatch`
|
|||
|
|
|
|||
|
|
步骤简述:
|
|||
|
|
|
|||
|
|
1. `CmdRpcEnvelope.parseFrom(raw)`。
|
|||
|
|
2. `protoRegistry.resolve(linkSource, serviceId, methodId)` → 可选的 **`ProtoInfo`**。
|
|||
|
|
3. 若存在 `ProtoInfo`:**解析 payload 为 CTS**、**创建 STC 的 `Builder`**(网络层职责,命令内只填字段)。
|
|||
|
|
4. 构造 **`CommandContext`**(含 `ChannelHandlerContext`、`CrossRpcInvoker`、解码结果等)。
|
|||
|
|
5. **`CmdRpcDispatch.dispatchEnvelope(in, lookup, cctx)`** → 执行具体 **`GameCommand`**。
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
flowchart LR
|
|||
|
|
IN[CmdRpcEnvelope in]
|
|||
|
|
PI{ProtoInfo 存在?}
|
|||
|
|
DEC[解码 CTS + STC Builder]
|
|||
|
|
RAW[decoded=null 由命令自处理]
|
|||
|
|
EXE[GameCommand.execute]
|
|||
|
|
OUT[CmdRpcEnvelope out]
|
|||
|
|
IN --> PI
|
|||
|
|
PI -->|是| DEC --> EXE
|
|||
|
|
PI -->|否| RAW --> EXE
|
|||
|
|
EXE --> OUT
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 4. 命令模型
|
|||
|
|
|
|||
|
|
| 类型 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| `GameCommand` | `execute(CommandContext, CmdRpcEnvelope)`,完全自控 payload。 |
|
|||
|
|
| `AbstractTypedPbCommand<C, B>` | 依赖 `ProtoInfo`;`run(ctx, cts, stcBuilder)`;回包信封 **复制** `service/method/cross_ret/link_seq`。 |
|
|||
|
|
|
|||
|
|
### `CommandSource` 与注册
|
|||
|
|
|
|||
|
|
- `@Cmd(source, serviceId, methodId)` 标注在命令类上。
|
|||
|
|
- **`SpringGameCommandRegistry`**:按 Spring 容器里 `GameCommand` Bean 扫描,**只收录** `source` 属于当前进程配置集合的命令(区服只收 `Client_TCP`,跨服只收 `CROSS_TCP`)。
|
|||
|
|
|
|||
|
|
## 5. `ProtoRegistry` 与自动注册
|
|||
|
|
|
|||
|
|
- **`ProtoRegistry`**:`register(ProtoInfo)` / `resolve(source, serviceId, methodId)`。
|
|||
|
|
- **`ProtoRegistryAutoConfigurer`**(`SmartInitializingSingleton`):扫描带 `@Cmd` 的 `GameCommand`,若继承 **`AbstractTypedPbCommand`**,则从泛型推断 **CTS / STC 类型** 并注册 **`ProtoInfo`**。
|
|||
|
|
- **未** 继承强类型基类的命令(如路径 3 中继)**不注册** `ProtoInfo`,由命令自行处理 payload。
|
|||
|
|
|
|||
|
|
## 6. `CrossRpcInvoker`
|
|||
|
|
|
|||
|
|
- 接口方法:`CmdRpcEnvelope roundTrip(CmdRpcEnvelope request)`。
|
|||
|
|
- **ServerModule** 中由 **`CrossTcpClient`** 实现:维护至跨服的 **长连接**、`link_seq` 多路复用、注册与心跳。
|
|||
|
|
|
|||
|
|
区服业务命令(路径 2/3)通过 **`CommandContext.crossRpc()`** 拿到该实例,向跨服发 **`CrossForward*`** 对应的信封。
|
|||
|
|
|
|||
|
|
## 7. 依赖说明
|
|||
|
|
|
|||
|
|
- **Spring Context**(`@Component` 等)、**Netty**、**protobuf-java**、**slf4j-api**、**Lombok**(可选)。
|
|||
|
|
- 生成的 proto Java 类来自 **ProtoBufModule**。
|
|||
|
|
|
|||
|
|
## 包结构(主要)
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
com.huangzj.base
|
|||
|
|
├── cmd # 分发、上下文、注册表、Proto 反射、CrossRpcInvoker
|
|||
|
|
├── frame # 长度前缀、Buf 工具
|
|||
|
|
├── net # CmdRpcTcpFrameHandler
|
|||
|
|
└── spring # SpringGameCommandRegistry、其它 Spring 辅助
|
|||
|
|
```
|