行会战报、拍卖列表这类大消息动辄几十 KB,单包下发时网关强制拆包,顺序乱了客户端拼出的就是乱码。分包策略在应用层主动拆包:每包一千四百字节、带序号与总数标记,客户端按序缓存、集齐重组,缺包主动补请求,大消息从此有序可控。
大消息按一千四百字节切片,每包头部带消息标识、当前序号与总包数;按序逐包发送,包间隔二十毫秒避免瞬时挤占带宽。示例代码如下:
-- 大消息分包:切片下发
local player = class(actor)
local CHUNK = 1400
local function sendChunks(player, msgId, payload)
local total = math.ceil(#payload / CHUNK)
for i = 1, total do
local piece = string.sub(payload, (i - 1) * CHUNK + 1, i * CHUNK)
sendluamsg(player, msgId, i, total, 0, piece)
setontimer(player, 0, 0, 20, 0)
end
end
客户端按序号缓存切片,集齐后拼接重组;发现缺包时主动请求重传缺失序号,重传三次仍缺则放弃本次消息并提示重新获取。示例代码如下:
-- 客户端重组:缓存与补拉
local player = class(actor)
local cacheBuf = {}
local function onChunk(player2, msgId, w1, w2, w3, sMsg)
cacheBuf[#cacheBuf + 1] = {idx = w1, total = w2, data = sMsg}
if #cacheBuf < w2 then return end
table.sort(cacheBuf, function(a, b) return a.idx < b.idx end)
local parts, missing = {}, 0
for i = 1, w2 do
if cacheBuf[i] and cacheBuf[i].idx == i then
parts[#parts + 1] = cacheBuf[i].data
else
missing = missing + 1
end
end
if missing == 0 then
SL:ShowSystemTips("战报接收完成:" .. #table.concat(parts) .. " 字节")
cacheBuf = {}
end
end
SL:RegisterLuaNetMsg(10001, onChunk, nil)
功能验证:五十 KB 消息拆三十六包按序到达、乱序注入后重组正确、缺包补拉三次后放弃并提示。弱网模拟丢包百分之五场景,重组成功率保持在九成九以上。线上监控大消息的包数分布与补拉率,补拉率高于百分之一说明网络质量差,把切片从一千四百字节降到一千字节提高通过率;单条消息上限五万字节,超限改分页。
切片曾按字符切,UTF8 汉字被拦腰斩断,重组后问号连篇,切片必须按字节且避开多字节边界。序号从零还是从一没约定,两端各按各的理解重组错位,协议字段写进两端共用文档。缓存曾不清理,上一条消息的残留切片混进下一条,消息标识字段加入后按标识隔离缓存,任何跨消息共享的缓冲都要按会话隔离。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 战士的烈火剑法一击熄火后要等八秒冷却,连招断档感强烈。疾风烈火斩在烈火剑法命中后给一次连击窗口:三秒内再…
实战应用:用在哪里 阵营对抗打到中期容易疲软:打赢没有额外好处,输掉也没有代价。阵营声望体系给阵营战装上荣誉刻度:个人与阵营…
实战应用:用在哪里 拿下沙巴克之后呢?城主除了名字挂在城墙上,对城市毫无影响。城主施政玩法让占领变成治理:城主每周获得市政令…
实战应用:用在哪里 主线路光缆被挖断的深夜,全服掉线 20 分钟,玩家以为游戏倒闭。备用线路方案给接入层配第二条出口:主线路…
实战应用:用在哪里 行会官员由帮主任命的老模式弊端明显:任人唯亲、能上不能下。行会选举接口把官员换届做成投票制:每两个月一次…
实战应用:用在哪里 烈火剑法的伤害加成、冷却时间、下一级提升,全靠玩家记忆或去官网查。技能说明悬浮卡片在鼠标悬停技能图标零点…