网络层不应该散在每个玩法脚本里
Godot 可以直接使用 HTTPRequest、WebSocketPeer、MultiplayerAPI 等能力。很多项目早期会在登录页写 HTTP 请求,在战斗脚本里写 WebSocket,在聊天 UI 里直接发消息。功能能跑,但一旦要做重连、鉴权、消息序列、错误码、弱网提示、日志追踪,就会发现网络逻辑散得到处都是。
商业客户端需要一个统一网络层。它不一定复杂,但要清楚拆分连接、协议、消息队列、领域分发和 UI 状态。Godot 的节点系统适合做表现,不适合让每个 Node 都直接拥有一条网络通道。
flowchart TD
A[NetworkService Autoload] --> B[Connection 管理]
A --> C[MessageCodec 编解码]
A --> D[RequestQueue 请求队列]
A --> E[Domain Dispatcher]
B --> F[WebSocket/HTTP]
E --> G[ChatModel]
E --> H[BattleModel]
E --> I[InventoryModel]
G --> J[UI/Gameplay Nodes]
H --> J
I --> J
连接管理和业务消息分开
连接管理负责连接、断开、心跳、重连、鉴权续期、网络状态。业务消息负责登录结果、聊天、战斗事件、背包变化。两者混在一起会让代码难以维护。比如重连成功后要重放哪些请求,是连接层提供状态,业务层决定恢复。
Godot 里可以让 NetworkService 做 Autoload,但它内部仍要拆对象。Connection 只关心 socket,Codec 只关心消息格式,Dispatcher 只把消息分发到模型。UI 不直接监听原始 socket,而是监听模型变化。
这样做还有一个好处:测试时可以替换连接层,用本地假消息驱动 UI 和玩法,不需要真实服务器。
请求队列要处理幂等和超时
客户端发出的请求应该有 request id、超时、重试策略和回调。不是所有请求都能重试。查询排行榜可以重试,购买道具不能随便重试,战斗输入可能走独立通道。请求队列要支持不同策略。
超时后 UI 要恢复状态,但请求结果可能之后才回来。客户端要能识别迟到响应。如果事务已取消或页面已关闭,响应不应再访问失效 Node。把回调绑定到模型或 Promise 风格对象,比直接回调 UI 节点更安全。
弱网下,队列还要限制并发。玩家连续点多个按钮,如果每个都发请求,失败提示会刷屏。可以对同类请求去重或合并,比如重复刷新背包只保留最后一次。
状态同步以模型为中心
服务器推送状态变化时,不要让 UI 直接改自己。比如背包变化推送到 InventoryModel,模型更新后发信号,背包 UI、红点、道具栏各自刷新。模型是客户端对服务器事实的本地镜像,UI 是表现。
战斗同步更复杂。位置、技能、伤害、Buff 都有时序。Godot 节点负责表现和插值,战斗模型负责事件顺序和权威状态。不要让某个角色 Node 直接处理所有网络包,否则角色销毁后消息就无处可去。
消息要有序列号或服务器时间。重连后可能收到补发消息,客户端需要去重和排序。没有序列,很多“偶现状态错乱”无法排查。
重连是业务流程,不只是 socket reconnect
断线后重新连上,只是第一步。客户端还要恢复登录态、同步玩家资料、查询未完成事务、恢复房间或战斗状态、刷新 UI。不同场景恢复策略不同:大厅可以刷新全量,战斗需要请求快照,商城购买需要查订单状态。
重连期间 UI 要明确:正在重连、可取消、已失败。不要让玩家还能继续点会发请求的按钮。重连成功后,也不要假设本地状态仍然正确。至少拉取关键模型版本,发现差异就刷新。
如果服务器判定会话过期,客户端要回登录或角色选择页,并清理敏感状态。不要在旧状态上继续操作。
网络调试要内置
网络问题最难靠截图排查。客户端应能导出最近请求和推送摘要:消息名、request id、耗时、错误码、重试次数、连接状态变化。正式包可以采样或脱敏,测试包则完整记录。
调试面板显示当前延迟、socket 状态、队列长度、最近错误和模型版本。Godot 导出到移动端后,控制台不一定方便看,游戏内诊断很重要。
小结
Godot 网络客户端不该让每个 Node 自己收发消息。用 NetworkService 管连接,用请求队列处理超时和幂等,用领域模型承接状态同步,用场景节点做表现,再把重连视为业务恢复流程。这样网络复杂度被收束在边界内,UI 和玩法才不会被弱网拖乱。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
我会在开发服提供一个网络模拟开关:延迟、丢包、断线、迟到响应、重复推送都能开。Godot 客户端在这种环境下跑得稳,真实网络环境才更有把握。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。