mirror of
https://github.com/layue13/MoonBridge.git
synced 2026-10-25 18:46:18 +00:00
feat: 与 TCP 并存的 WebSocket 玩家监听
新增可选 websocket 配置段,在原有 TCP listen 之外再开一个 WebSocket 监听, 供经 CDN 接入的客户端使用;两种入口共用会话、选服、转服和 maxConnections。 - core.websocket:升级握手(可选 TLS)、二进制消息与 Minecraft 字节流互转、 可信代理真实 IP(X-Forwarded-For 从右取第一个不可信地址 / CF-Connecting-IP 等) - SessionChannels.clientAddress 统一玩家地址,用于两类准入事件、Mojang 验证 IP 与 Bungee 转发 - ConnectionGate 支持升级后才加入管线;登录等待守卫放在 WebSocket 适配器之后 - 未升级连接计入 maxConnections,并受 handshakeTimeoutSeconds 约束 - 测试:真实 socket 上 TCP 与 WebSocket 并存登录与转发、分片/合并/Ping、 在线模式加密与转发 IP、不可信来源、404/文本帧、名额归还、wss 证书加载 - 文档:docs/websocket.md,并更新运行配置、插件、架构与默认配置示例 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GGL9BudzWm4dUQgBsQw4Qr
This commit is contained in:
27 files changed
+1477
-29
No files matched your search
@@ -32,7 +32,7 @@ The slow tests are the session integration tests (`ProxySessionListenerTest`, `S
|
||||
|
||||
**Session threading.** `ProxySessionListener` owns the listener, event loops and the UUID→session index. Each `Session` (one per player connection) confines its mutable state to the frontend event loop, and its backend channels are created on that same loop (`SessionChannels.backendBootstrap` enforces it). Login verification, backend DNS and plugin callbacks run off that loop and re-enter it by posting a task; results are checked against the current connection identity so a stale async result cannot act on a reconnected player. Plugin work goes through bounded pools that reject when full.
|
||||
|
||||
**Session layout.** `core.session` holds `Session` (the Netty handler and lifecycle owner) plus the pieces it delegates to: `FrontendLogin` (handshake, status, encryption, Mojang verification), `InitialRouter` (placement decision and first backend dial), `BackendHandshakes`. `core.session.transfer` is `TransferCoordinator`, which reaches the session only through the `TransferHost` port (Session supplies it as an adapter) and owns all transfer state. `core.session.play` has the per-frame PLAY handlers and relay start-up buffering; `core.session.channel` has backend dialing and pipeline lookups. Dependencies point one way: `session` -> `transfer` -> `play`/`channel`.
|
||||
**Session layout.** `core.session` holds `Session` (the Netty handler and lifecycle owner) plus the pieces it delegates to: `FrontendLogin` (handshake, status, encryption, Mojang verification), `InitialRouter` (placement decision and first backend dial), `BackendHandshakes`. `core.session.transfer` is `TransferCoordinator`, which reaches the session only through the `TransferHost` port (Session supplies it as an adapter) and owns all transfer state. `core.session.play` has the per-frame PLAY handlers and relay start-up buffering; `core.session.channel` has backend dialing, pipeline lookups and `clientAddress` (the player IP: a trusted forwarded address or the socket peer; use it instead of `remoteAddress()`). `core.websocket` is the optional WebSocket frontend; after the upgrade the pipeline behind `WebSocketFrameAdapter` is the same as for TCP. Dependencies point one way: `session` -> `transfer` -> `play`/`channel`.
|
||||
|
||||
**Data path.** After login, `RawRelay` forwards already-framed PLAY frames between the two channels without copying. Per-frame concerns are separate inbound handlers (`KeepAliveBridge`, `PlayerCommandInterceptor`, `TabCompletionBridge`, `TransferFrameHandler`) in front of the relay. Backpressure works by pausing reads on the source when the peer is not writable; the relay flushes once per read batch (`channelReadComplete`).
|
||||
|
||||
|
||||
Reference in new issue
Block a user