同一玩家的两条消息走了不同的处理路径,先发的后到,装备穿上的消息比脱下的消息晚处理,面板状态错乱。消息有序性给每个玩家的消息加单调递增序号,处理端按序号顺序消费,乱序消息先入等待区补位,保证同一玩家的消息严格按序处理。
消息推送前从玩家的序号计数器取号,序号随消息一起下发,同一玩家的消息序号连续且递增。
local seqTable = {}
local function nextSeq(actor)
local seq = (seqTable[actor] or 0) + 1
seqTable[actor] = seq
return seq
end
local function pushOrdered(actor, payload)
local seq = nextSeq(actor)
sendluamsg(actor, 7402, seq, 0, 0, payload)
end
接收端维护每个玩家的已消费序号,乱序到达的消息先入等待区,等缺口序号补齐后按序释放,超时未补齐的走全量校准。
local waitArea = {}
local consumed = {}
local function consumeOrdered(actor, seq, payload)
local expect = (consumed[actor] or 0) + 1
if seq ~= expect then
waitArea[actor] = waitArea[actor] or {}
table.insert(waitArea[actor], { seq = seq, payload = payload })
return
end
consumed[actor] = seq
handle(payload)
drainWaiting(actor)
end
构造乱序、缺号、重复三类异常序列验证处理次序;同一玩家并发推送一百条,接收顺序与发送顺序一致;等待区的补位在缺口到达后自动释放。监控等待区的积压条数,条数持续增长说明有消息永久丢失,触发全量校准兜底。
序号在服务重启后从一重新计数,老客户端沿用大序号把新消息全部判成乱序丢弃,重启后广播序号基线重置。等待区只进不出撑爆内存,补一条 10 秒的过期清理,过期的乱序消息直接走全量校准。payload 里携带玩家自填文本时含特殊字符,等待区比较逻辑把不同消息误判为同一条,比较键改用纯序号。多线程处理端各领各的序号并发处理,顺序又被打破,处理端改成单线程顺序消费。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 行会活动集中在攻城战,日常缺乏轻量社交场景。行会篝火答题做行会固定社交活动:每周三、周日晚在行会驻地点燃…
实战应用:用在哪里 全服答题活动办过几期,参与的人不少但黏性不足,答完就散。科举答题把答题做成两段式:每天晚八点的乡试答题筛…
n n n 实战应用:用在哪里 n战斗中打字沟通慢且危险,队伍协作靠喊话效率太低。快捷短语栏在屏幕底部提供八条可自定义的战斗…
n n n 实战应用:用在哪里 n龙脉区域的野外宝箱是散人玩家的每日福利:每逢整点在龙脉区域随机刷新十五个宝箱,分三档给不同…
实战应用:用在哪里 同一玩家的两条消息走了不同的处理路径,先发的后到,装备穿上的消息比脱下的消息晚处理,面板状态错乱。消息有…
实战应用:用在哪里 战斗日志全量打印,一天写满一块硬盘,翻日志像大海捞针。日志采样按类别分策略:错误日志全量保留、行为日志按…