HTTP 轮询的实时性不足导致聊天消息延迟 3 秒以上,改用 WebSocket 长连接后消息延迟降到毫秒级。WebSocket 接入方案覆盖握手认证、心跳保活与消息推送三个环节,长连接的建立让服务端可以主动向客户端推送数据。
客户端发起 WebSocket 连接时携带登录 Token,服务端校验 Token 后绑定会话,后续消息通过会话标识路由到对应玩家。
local sessions = {}
local function onWebSocketOpen(actorId, token)
local expected = getplayvar(actorId, "HUMAN", "LOGIN_TOKEN") or ""
if token ~= expected then
sendmsg(actorId, 0, "会话认证失败,请重新登录")
return false
end
sessions[actorId] = { token = token, ts = os.time() }
return true
end
WebSocket 长连接需要定期心跳保活,服务端每 30 秒发送 Ping 帧,客户端回复 Pong 帧确认存活,120 秒未收到 Pong 判定断线。
local HEARTBEAT_SEC = 30
local TIMEOUT_SEC = 120
setontimerex(230, HEARTBEAT_SEC)
function ontimer230()
local now = os.time()
for actorId, session in pairs(sessions) do
if now - session.ts > TIMEOUT_SEC then
sessions[actorId] = nil
sendcentermsg(actorId .. " 连接超时断开")
else
sendluamsg(actorId, 7501, 0, 0, 0, "ping")
end
end
end
握手认证验证 Token 过期、Token 错误与正常连接三种场景;心跳保活验证 120 秒超时断线检测;长连接在弱网环境下的稳定性测试覆盖延迟 200 毫秒与丢包 5% 两个场景。监控 WebSocket 长连接的在线数量与心跳超时断开的次数,断开率突增说明网络质量在恶化。
Token 校验从缓存读取存在秒级延迟,刚登录的玩家立即建立 WebSocket 连接时 Token 尚未写入缓存导致认证失败,Token 写入后增加 1 秒的宽限期。心跳 Ping 帧的发送频率过高导致带宽浪费,30 秒一次在实时性与带宽之间取得平衡。断线检测的超时时间 120 秒对移动网络太短,移动网络切换基站时可能超过 120 秒无响应,超时时间放宽到 180 秒。WebSocket 连接数超过单进程上限时需要多进程部署,会话路由改为一致性哈希。
心跳间隔要小于网关层空闲超时的一半,否则连接会被中间设备提前掐断,表现为客户端收不到任何断开事件,消息静默丢失。重连成功后先补一次全量拉取再做增量订阅,顺序颠倒会出现短暂的数据空洞,玩家看到的聊天记录缺少最近几条,排障时容易被误判为丢包。
网关发布要支持滚动重启:新连接进新进程,旧连接等待自然下线或迁移,重启期间聊天不中断。上线初期先接聊天频道,验证稳定后再接入交易与组队信令,逐路迁移把风险拆小,任何一路异常都能单独回退。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 装备回收商 NPC 每天按评分收购玩家的装备,裁决之杖、骨玉权杖按攻击、持久加权打分,榜上只要前五名。数…
实战应用:用在哪里 沙巴克攻城是全服行会战的最高舞台:攻方砸开城门、抢占皇宫,守方依托城墙与复活点反打。规则设计的关键是节奏…
实战应用:用在哪里 影分身玩法给法师职业补上生存短板:危急时刻召唤四个影分身分担仇恨,敌人需要在六格范围内分辨真身,猜错就浪…
实战应用:用在哪里 组队邀请、行会宣战这类关键信令丢了没有兜底,玩家只能反复手点,高峰期体验很差。重试机制给信令加确认回执:…
实战应用:用在哪里 新资料片上线首日预约量常是日常十倍,一口气全开会让数据库与登录网关同时过载。滚动开区把开区动作排成队列:…
实战应用:用在哪里 百人同屏的沙巴克外围战场,每个玩家每秒跑动会触发数次位置更新,全部即时下发时广播量随人数平方增长,网关先…