拍卖行竞拍高峰,一件屠龙刀 1 秒能产生 60 条竞价事件,逐条 sendluamsg 下发,竞拍面板每秒重建 60 次,低端机直接卡死。消息合并把同一玩家的多条事件收进 1 秒窗口,打包成一条消息下发,回调次数降到百分之一。合并的收益在客户端侧最明显:回调次数、界面重建次数、GC 压力三项同步下降,低端机卡顿帧比例从两成降到 3% 以内。合并对发起方同样友好,下行包量降到原来的 2%,网关带宽压力同步缓解。
每个玩家一条缓冲队列,事件先入队,全局定时器每 1 秒统一打包,用换行符拼接后单次下发,队列即发即清。
local W = {}
function pushAuction(actor, txt)
local q = W[actor] or {}
table.insert(q, txt)
W[actor] = q
end
setontimerex(134, 1)
function ontimer134()
for actor, q in pairs(W) do
if #q > 0 then
sendluamsg(actor, 7002, 0, 0, 0, table.concat(q, "\n"))
W[actor] = {}
end
end
end
窗口内超过 40 条折叠成摘要,避免单包过大;离线玩家的残留队列每 60 秒清一轮,缓冲表不无限膨胀。
local LIMIT = 40
function pushAuction(actor, txt)
local q = W[actor] or {}
if #q >= LIMIT then
q[LIMIT] = "另有更多竞价已折叠"
else
table.insert(q, txt)
end
W[actor] = q
end
setontimerex(135, 60)
function ontimer135()
for actor, q in pairs(W) do
local p = getplayerbyname(actor)
if not (p and isplayer(p)) and #q > 0 then
W[actor] = nil
end
end
end
压测 60 条每秒注入单玩家队列,核对客户端回调次数从 60 降到 1;41 条事件核对第 40 条被摘要折叠;下线玩家的残留队列 60 秒内清除。多玩家并发场景抽 10 个账号交叉注入,核对各自队列互不串包。监控单包字节量与折叠触发次数,折叠率长期高于两成说明窗口该缩短。单包体积上限 8KB 校验,超限提前分片下发,不靠折叠文案硬扛。
合并包用换行拼接,客户端按行拆分时漏了末行没有换行符的情况,末条竞价显示丢失,拼接改成行间插入、首尾不加。事件顺序按入队顺序天然保序,但折叠后序号会跳,客户端进度条按序号推进而错位,改成按条数推进。离线清理遍历的是玩家名键,重名改名窗口期出现误判,清理动作改成只清队列非空的键并二次校验。合并窗口 1 秒是引擎定时器的粒度下限,想要 200 毫秒窗口的方案在网关层做,引擎侧做不了。合并包为空时 sendluamsg 的变参被引擎裁参报参数不足,空队列跳过发送的判断补在定时器入口。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 祖玛教主全服首杀出了大事:行会 A 磨掉九成血,行会 B 赶来收下终结一击,系统按击杀者把首杀公告给了 …
实战应用:用在哪里 PK 值 200 以上进红名村,出来靠洗红任务:击杀红名村恶徒掉善恶令,红名村老者按每枚减 10 点 P…
实战应用:用在哪里 烈火剑法常年压在 8 号槽,手指够不着,想换到 2 号槽。技能栏交互做两次点击交换:点源槽高亮选中,点目…
实战应用:用在哪里 玩家对固定地图刷腻了,缺一个全服一起动的探索玩法。藏宝罗盘每天 8 点在全服刷 3 个藏宝点,罗盘道具指…
实战应用:用在哪里 商人号每天从系统商店搬 5 万瓶金创药去摆摊倒卖,药品市场翻着倍涨。物价平准机制让系统商店的畅销品随全服…
实战应用:用在哪里 经济类投诉最怕说不清:玩家说商店多扣了钱,运营翻不出账。日结对账把发放侧与消耗侧各立一个计数器,全天累加…