概念
架构
两个进程、九个模块、一条控制通道:大厅负责实例与分配,房间负责权威对局,客户端只跟房间说话。
CrossingNet 的部署形状是两个进程:
Lobby(大厅进程) Room(房间进程,一台机器可跑多个)
UCrossingSessionSubsystem UCrossingRoomSubsystem
UCrossingMatcherSubsystem ACrossingGameMode
UCrossingProfileSubsystem ACrossingPlayerState
UCrossingAdminSubsystem ACrossingPlayerController
UCrossingPartySubsystem
控制端口 57300 ◄──── 二进制 CMD ────► 健康端口 58100+
游戏端口 57200 ──────── 分配旅行 ──────► 游戏端口 57000+- 大厅不跑对局:它管理实例(拉起、探测、回收)、跑匹配、存档案、做结算落盘。
- 房间只跑一局:权威 GameMode、座位、准备、投票、系列赛,结束时把结果发回大厅。
- 客户端从不直接跟大厅的控制端口说话:拿到地址和票据后,直接旅行进房间。
模块
| 模块 | 子系统 / 类 | 管什么 | 不管什么 |
|---|---|---|---|
| Identity | UCrossingIdentitySubsystem、ACrossingPlayerState、ICrossingAuthProvider | 分配 CrossingPlayerId 并复制;Guest 与团队账号 | UniqueId(无 OSS 时无效) |
| Session | UCrossingSessionSubsystem | 进程/端口/健康/状态机/回收/占位/预热池/结算日志/重连登记 | 身份;只按人数 |
| Room | UCrossingRoomSubsystem | 座位/准备/开局/结算/健康回复/重连/投降/系列赛 | 匹配和旅行 |
| Match | UCrossingMatcherSubsystem、ICrossingMatchDimension、IMatchPolicy | 队列/配对/质量/自动拉起/补位 | 不直接建实例(调 Session) |
| Party | UCrossingPartySubsystem | 建队/邀请/整队入队/返回/重开 | 跨局社交关系 |
| Profile | UCrossingProfileSubsystem、UCrossingProfileStore | 档案块/分块传输/Elo/战绩/赛季/行为分 | 账号系统 |
| Admin | UCrossingAdminSubsystem | 踢人/封禁/强制结算/关实例 | 权限系统 |
| Events | UCrossingEventsSubsystem | 35 个蓝图事件 | 业务状态 |
| Net | ACrossingGameMode、ACrossingPlayerController、CrossingControlProtocol | 旅行/RPC/票据/控制帧 | 业务判定 |
| LAN | UCrossingLANSubsystem | UDP 发现/开房广播/直连 | 认证与加密 |
端到端:一次正常匹配
客户端 大厅 房间
│ ServerEnqueueMatch │ │
├──────────────────────────────►│ QueueJoin │
│ │ 配对(维度 / Party / Elo) │
│ │ 无实例 → 预热池认领或 SpawnInstance
│ │◄──────── 健康 READY ────────────┤
│◄── ClientStartReadyCheck ─────┤ │
│ ServerReadyCheckReply ✓ │ │
├──────────────────────────────►│ ReserveSlot(+1) │
│◄── ClientReceiveAssignment ───┤ 地址 / 端口 / token / trace │
│ ClientTravel ──────────────────────────────────────────────────►│ 校验 token
│ │ │ SeatAssigned
│ ServerSetReady(true) ──────────────────────────────────────────►│ ReadyChanged
│ │ │ GameStart
│ │ │ EndGame
│◄── ClientReturnToLobby ───────┤◄──── RESULT + ACK ──────────────┤
│ 回大厅 │ 结算幂等落盘 │跨进程只有三样东西:分配结果(地址、端口、票据)、结算结果、控制命令。其余都在进程内。
控制通道
大厅与房间之间的控制面是二进制帧:
[u32 length][u8 type][u32 reqId][payload]| 类型 | 值 | 方向与用途 |
|---|---|---|
Cmd | 1 | 大厅 → 房间:STATUS / STOP / INFO / SETMATCH |
CmdAck | 2 | 房间 → 大厅:确认收到并执行 |
Hello | 3 | 房间 → 大厅:启动握手 |
Health | 4 | 房间 → 大厅:健康上报 |
Event | 5 | 房间 → 大厅:事件推送 |
Result | 6 | 房间 → 大厅:结算结果 |
reqId 幂等缓存,同一个 reqId 重发不会执行两次;文本路径保留为回退。
细节见协议。
重连
房间掉线 → 保留座位 + 推 DISCONNECT;instance;player;expires
→ 大厅 ReconnectRegistry 记录
客户端重启 → 回大厅 → ServerReconnect()
→ 大厅 ConsumeReconnect → 签发 role=ReconnectPlayer 的票据
→ 分配回原实例 → 旅行
房间 → TryReclaimSeat 恢复座位 → 推 RECONNECTED → 照常结算,不按 Forfeit票据里的角色决定房间怎么对待它:Player 分新座位,ReconnectPlayer 回原座位,
Spectator 进观战列表,LateJoinPlayer 走迟到补位。
扩展点
| 扩展点 | 方式 |
|---|---|
| 身份 | 实现 ICrossingAuthProvider,注册进身份子系统 |
| 匹配维度 | Dimensions.Add(MakeShared<你的维度>()) |
| 匹配策略 | 实现 IMatchPolicy(默认 FGreedyWindowPolicy) |
| 进程拉起 | 实现 ICrossingSpawner(默认 FProcessSpawner) |
| 评分规则 | CrossingRating::RegisterRule(默认 Elo / Placement) |
| 档案存储 | UCrossingProfileSubsystem::RegisterStoreFactory(默认 File) |
| 档案块 | RegisterBlock(Name, UScriptStruct*, SchemaVersion, bRequiredAtLogin) |
边界
| 插件负责 | 项目负责 |
|---|---|
| 身份分配与复制 | 真实登录、账号系统、封禁的登录拒绝点 |
| 实例生命周期与端口 | 进程守护、可执行文件 |
| 匹配与分配 | 玩法规则、房间内胜负判定 |
| 结算与 Elo 落盘 | 长期数据仓库、运营后台 |
| 事件广播 | 表现层:UI、音效、镜头 |
下一页:生命周期。