玩家掉线 20 秒重连,期间队伍杀了 BOSS、领了奖励、换了地图——重连后的界面如果还是旧数据,玩家的第一反应是东西被吞了。断线期间的消息补偿机制把增量变化在重连时一次性补发,界面的数据无缝衔接。
---服务端:每条下发消息携带递增序号
function ReliableSend(actor, msgType, payload)
actor.seq = (actor.seq or 0) + 1
sendmsg(actor, msgType, actor.seq .. ":" .. payload)
pendingForSeq(actor, actor.seq, payload)
end
每个玩家的下发消息带递增序号,序号与内容暂存到补偿缓冲。客户端重连时上报自己收到的末位序号,服务端从序号之后把缓冲的增量补发,中间的空洞被精确填补。
---重连触发:按客户端上报的序号补发增量
function playreconnection(actor, lastSeq)
local buffered = actor.seqBuffer
if lastSeq and buffered and lastSeq < actor.seq then
local resend = 0
for seq = lastSeq + 1, actor.seq do
if buffered[seq] then
sendmsg(actor, msgType, seq .. ":" .. buffered[seq])
resend = resend + 1
end
end
sendmsg(actor, 1, "已为玩家补同步掉线期间的 " .. resend .. " 条变化")
end
end
补发只发缓冲里存在的增量,时效性消息(已过期的活动提示)跳过。补发的总量上限 200 条,超过按重要级筛选,防止长时间掉线后的洪水式同步。缓冲的容量按玩家保留最近 500 条,容量与掉线时长的容忍窗口匹配。
重连补发的触发率与补发条数分布统计,玩家重连后的困惑工单数量是补偿有效性的直接反馈。
序号的递增曾经在重连后清零重新计数,客户端拿新旧序号比对全乱了,序号改为登录会话内单调递增且跨重连延续。补偿缓冲的清理时机漏了玩家换线,换线后的旧线消息补发到新线,缓冲按线区分后修复。
补偿机制只覆盖数据变化类消息,战斗表现类的实时消息不补偿(过时的技能特效没有意义)。重连补发的流量要有上限,洪水式的补发本身会造成二次卡顿。客户端收到补发消息时界面做聚合刷新,逐条跳变的刷新观感差且浪费渲染。
本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 新值班排查“玩家丢装备”,翻日志的关键词全靠问老员工。检索模板库把常见故障的日志关键词、过滤条件、排查步…
实战应用:用在哪里 玩家申诉“我的宝石昨天还在”,没有昨天的数据就无从核对。快照比对方案:每日零点给热键做快照存档,申诉时拿…
实战应用:用在哪里 值班早上一上班先手动点一圈服务状态,漏检一项就是隐患过夜。夜间巡检把健康检查脚本化:凌晨四点自动跑十四项…
实战应用:用在哪里 副本里的语音指引报点很贴心,但老玩家听八百遍“注意走位”只想静音。语音指引开关方案:总开关加分类开关两级…
实战应用:用在哪里 新服开荒四千人同时挤登录,服务器只放得下两千。排队系统把超出部分编队:客户端每十秒收一次排队位置推送,回…
实战应用:用在哪里 异地登录的提醒邮件玩家未必看得到,短信验证码是触达率最高的确认通道。方案:陌生设备登录触发短信验证,验证…