RhythMC-Reborn 网络架构文档
目录
架构概述
RhythMC-Reborn 采用 双通道通信架构,结合 HTTP/2 和 WebSocket 实现高效可靠的网络通信:
设计原则
| 原则 | 描述 |
|---|---|
| 安全优先 | /server/login 使用 bootstrap Bearer 建立服务器身份,后续业务接口使用短期 access token |
| 异步非阻塞 | 所有网络操作使用 CompletableFuture |
| 自动重连 | WebSocket 支持指数退避重连 |
| 资源完整性 | 优先使用 SHA256 校验,缺失时回退 SHA1 |
| 短期令牌刷新 | serverAccessToken 10 分钟有效,WS 掉线后优先刷新 |
| 离线容错 | 网络故障时自动降级为离线模式 |
核心组件
1. NetworkManager (网络管理器)
位置: cn.frkovo.rhythmcv2.Network.NetworkManager
职责: 网络模块的总入口,协调所有网络组件
核心字段:
| 字段 | 类型 | 描述 |
|---|---|---|
okHttpClient | OkHttpClient | HTTP/WebSocket 共享客户端 |
httpClient | HttpClient | HTTP 请求封装 |
webSocketClient | WebSocketClient | WebSocket 连接管理 |
serverSession | ServerSession | 服务器会话状态 |
rivalUpdateManager | RivalUpdateManager | 对手同步管理 |
resourceIntegrityManager | ResourceIntegrityManager | 资源完整性管理 |
生命周期:
NetworkManager 登录成功后,会把资源完整性校验、收藏品同步、ResourcePackManager.init() 远程资源包列表加载并行执行;三者全部成功才进入在线模式。资源包列表现在由 GET /resources/packmanifest 直接返回 url 与 size 字段,插件不再额外请求单独的资源包 URL 接口;账户设置中的资源包菜单会使用这些元数据展示 FULL 包和各 Chapter 包的可读大小。若服务器登录第一步失败,或后续任一初始化任务失败,则会先注册 ResourcePackManager 的本地 song-pack fallback,再切换到离线模式。
2. HttpClient (HTTP客户端)
位置: cn.frkovo.rhythmcv2.Network.HttpClient
职责: 封装 OkHttp 提供异步 HTTP 请求
支持的方法:
| 方法 | 返回类型 | 描述 |
|---|---|---|
get(url) | CompletableFuture<String> | GET 请求 |
post(url, jsonBody) | CompletableFuture<String> | POST JSON 请求 |
postWithStatus(url, jsonBody) | CompletableFuture<HttpResult> | POST 并返回状态码 |
download(url, dest, progress) | CompletableFuture<Path> | 文件下载(支持进度回调) |
认证: NetworkManager 在 /server/login 使用 Authorization: Bearer <serverBootstrapToken> 完成服务器登录。登录成功后,仅对受保护后端接口自动注入 Authorization: Bearer <serverAccessToken>;Mojang API、资源下载直链与外部 CDN 请求不会携带该头。
令牌生命周期: serverAccessToken 为 10 分钟短期令牌。NetworkManager 在 WebSocket 非预期断开后调用 /server/refresh 获取新的 accessToken;若刷新失败,则使本地 token 失效并执行完整重登录。
3. WebSocketClient (WebSocket客户端)
位置: cn.frkovo.rhythmcv2.Network.WebSocketClient
职责: 管理实时双向通信
特性:
- 自动重连: 支持指数退避重连策略
- 消息分发: 基于监听器模式的消息分发
- 状态管理: 维护连接状态 (OFFLINE/CONNECTING/ONLINE/LAGGING)
- Bearer 鉴权: 握手请求携带
Authorization: Bearer <serverAccessToken> - 断线恢复: 瞬时断链时持续重连 WebSocket;仅在握手返回
401/403且/server/refresh失败后才整套重新登录
重连策略:
重连延迟计算: delay = reconnectDelayMs * 2^min(retryCount, maxRetry - 1),达到退避上限后继续按该上限间隔重试,不会仅因 WebSocket 中断直接进入离线模式。
4. ServerSession (服务器会话)
位置: cn.frkovo.rhythmcv2.Network.ServerSession
职责: 存储服务器连接状态信息
字段:
| 字段 | 类型 | 描述 |
|---|---|---|
sessionID | String | 本地运行时标识 |
serverID | int | 服务器在远程的注册ID |
serverName | String | 服务器名称 |
assetServer | String | 资源服务器地址 |
accessToken | String | 短期 Bearer 令牌(登录响应后赋值) |
wsServer | String | WebSocket服务器地址 |
status | NetworkStatus | 网络状态 |
通信协议
双通道设计
| 通道 | 协议 | 用途 | 特点 |
|---|---|---|---|
| HTTP通道 | HTTP/2 + JSON | 登录、资源下载、数据上传 | 可靠、有序、支持重试 |
| WebSocket通道 | WebSocket + JSON | 实时游戏同步 | 低延迟、双向、实时 |
安全机制
服务器登录与运行时 Bearer
登录配置:
| 配置项 | 值 |
|---|---|
| 传输协议 | HTTPS (TLSv1.3) |
| 登录凭证 | net.server-login-token |
| 发送方式 | /server/login 请求头中的 Authorization: Bearer <serverBootstrapToken> |
| 后续鉴权 | Authorization: Bearer <serverAccessToken> |
作用范围: bootstrap token 仅用于 /server/login 阶段,完成服务器身份建立。登录成功后的业务请求依赖短期 Bearer access token;资源下载与第三方接口不复用 bootstrap token。
配置要求:
# config.yml
net:
server-login-token: "eyJhbGciOiJIUzI1NiJ9..."
流程图
整体初始化流程
掉线恢复流程
登录认证流程
WebSocket 消息流程
离线模式切换流程
配置说明
必需配置项
net:
# 游戏服务器地址
game-server: "https://api.rhythmc.example.com"
# WebSocket重连配置
max-retry: 5
reconnect-delay-ms: 1000
# 服务器 bootstrap token
server-login-token: "eyJhbGciOiJIUzI1NiJ9..."
# 资源包回退配置
resource-pack-fallback:
url: "https://fallback.rhythmc.example.com/pack.zip"
auth-type: "token"
token: "your-token"
网络状态枚举
NetworkStatus
| 状态 | 显示 | 描述 |
|---|---|---|
| OFFLINE | 🔴 | 离线模式 |
| CONNECTING | 🟡 | 连接中 |
| ONLINE | 🟢 | 在线 |
| LAGGING | 🟠 | 延迟较高 |
PlayerNetStatus
| 状态 | 描述 |
|---|---|
| OFFLINE | 离线模式 (不上传数据) |
| LOGIN | 登录中 |
| CONNECTED_OFFLINE | 盗版登录 |
| CONNECTED_ONLINE | 正版登录 |
2026-03-16 Update: Active Chart Catalog
NetworkManager.initialize() now includes one more authenticated bootstrap request:
GET /server/charts
The startup pipeline now treats the following as parallel initialization tasks after /server/login succeeds:
- resource integrity verification
/server/collections- remote resource pack manifest loading
/server/charts
The chart-directory response is converted into an ActiveChartCatalog and stored in ConfigManager.
Runtime effect:
- if the catalog is unavailable, the client keeps the old behavior and loads every local chart under
Data/Charts - if the catalog is available,
RawSongDeserializeronly loads songs and difficulty slots that are marked active by the backend
This keeps the backend focused on active chart metadata only. Manifest-heavy fields stay in local chart files after resource sync.
See also: