# ServerModule **区服进程**:同时提供 - **客户端游戏 TCP**(`game.client-tcp.port`,默认示例 **9091**):`CommandSource.Client_TCP` - **连跨服的出站 TCP 长连接**(`cross.host` / `cross.port`,示例 **9200**):由 **`CrossTcpClient`** 维护,`ProtoRegistry` 中对应逻辑仍按跨服协议,但 **连接发起在区服** - **HTTP**(`server.port`,默认 **8080**):Demo API、探针、静态探测页 ## 总体数据流 ```mermaid flowchart TB subgraph External["外部"] GAME[游戏客户端 TCP] BROWSER[浏览器 / HTTP 客户端] end subgraph Server["ServerModule"] CTS[ClientTcpServer :9091] HTTP[HTTP :8080] REG[ServerCommandRegistry] C2[TcpPath2 等命令] CC[CrossTcpClient 长连接] end subgraph Cross["CrossModule :9200"] XT[Cross TCP] end GAME --> CTS --> REG --> C2 BROWSER --> HTTP C2 --> CC --> XT ``` ## 1. 客户端 TCP(主入口) - **`ClientTcpServer`**:`ApplicationReadyEvent` 后绑定端口(`@Order` 较早,保证先于跨服预热)。 - **`ClientTcpChannelInitializer`**:解码器 + **`CmdRpcTcpFrameHandler`**(`linkSource = Client_TCP`,注入 **`ServerCommandRegistry`** 与 **`CrossTcpClient`** 作为 **`CrossRpcInvoker`**)。 ```mermaid sequenceDiagram participant C as 客户端 participant S as ClientTcpServer participant R as ServerCommandRegistry participant Cmd as GameCommand participant X as CrossTcpClient C->>S: 帧: CmdRpcEnvelope S->>R: resolve(service, method) R->>Cmd: execute opt 路径2/3 Cmd->>X: roundTrip(跨服信封) X-->>Cmd: 跨服响应 end Cmd-->>S: 响应 CmdRpcEnvelope S-->>C: 帧 ``` ### 三条路径(概念对照) | 路径 | Client TCP service/method | 是否调跨服 | 说明 | |------|---------------------------|------------|------| | 1 | Service_1 / Method1 | 否 | Echo | | 2 | Service_2 / Method2 | 是 | `CrossProxy*` → 转 `CrossForward*` → 跨服 → 回写 `CrossProxyStc`(含 `server_note`) | | 3 | Service_3 / Method3 | 是 | 信封对客户端为 S3,payload 为 `CrossForwardCts`;区服只转发跨服 | 实现类:`TcpPath1LocalEchoCommand`、`TcpPath2CrossThenServerCommand`、`TcpPath3CrossRelayCommand`。 ## 2. 区服 → 跨服:`CrossTcpClient` - **单连接长连**:`ensureConnected()` 建链;断线后 `linkRegistered=false`,下次业务或心跳会重建。 - **注册**:`Service_4` + `Register`,载荷 `CrossLinkRegisterCts`(`cross.server-id`、`cross.token`)。 - **心跳**:`CrossTcpHeartbeatTask` 按 `cross.heartbeat-interval-ms`(默认 15000)调用 `sendHeartbeat()`(`Service_4` + `Heartbeat`)。 - **多路复用**:每次 `roundTrip` 分配 **`link_seq`**,在 `pendingBySeq` 中挂 `CompletableFuture`;入站 **`dispatchInbound`** 按 `link_seq` 完成 Future。 ```mermaid stateDiagram-v2 [*] --> Disconnected Disconnected --> Connected: ensureConnected Connected --> Registered: Service_4 Register OK Registered --> Registered: roundTrip / Heartbeat Registered --> Disconnected: 断链 / 心跳失败 ``` - **预热**:`CrossTcpClient.warmupCrossLink()` 监听 `ApplicationReadyEvent`(`@Order` 较低,在 **`ClientTcpServer` 绑定之后**),提前建链+注册。 配置示例见根目录 `README.md` 或本模块 `application.yml`: - `cross.host`、`cross.port`(须与 CrossModule `cross.tcp.port` 一致) - `cross.server-id`、`cross.token`、`cross.heartbeat-interval-ms` ## 3. HTTP - **`/api/ping`**(`PingController`):探活。 - **`/api/config/client-tcp`**(`ClientTcpConfigController`):返回 `game.client-tcp.port`。 - **`/api/demo/*`**:Mongo / Redis / 事件 / 模块 tick 等演示接口(见 `DemoApiController`)。 ## 4. 其它 Demo(非网络核心) - MongoDB / Redis / 事件 / 玩家模块 tick 等:见 `com.huangzj.server` 下 `web`、`mongo`、`redis`、`module` 等包。 ## 5. 本机命令行压测三条 TCP 路径 `com.huangzj.server.demo.TcpPathsDemo`:与客户端相同帧格式,默认 `127.0.0.1:9091`。 ```bash java -cp ... com.huangzj.server.demo.TcpPathsDemo [host] [port] ``` ## 6. 日志 - `app.logging.dir`:默认 `logs/ServerModule` - `logback-spring.xml`:`info.log`(INFO+WARN,不含 ERROR)与 `error.log`(仅 ERROR) ## 7. 启动顺序建议 1. 启动 **CrossModule**(端口 9200)。 2. 启动 **ServerModule**(HTTP 8080,客户端 TCP 9091)。 3. 用 `TcpPathsDemo` 或自建 TCP 客户端按路径 2 组帧,可验证经区服到跨服的全链路。