强更做不到时就共存:大版本推送的两周窗口里,新旧两版客户端同时在线,服务器要同时说两套协议。协议版本兼容的设计要点是握手时报版本、按版本路由处理器、字段变更只增不删,三条纪律撑住共存的过渡期。
---登录握手:客户端上报协议版本
function Handshake.onLogin(actor, ver)
actor.protoVer = ver
if not PROTO_SUPPORTED[ver] then
sendmsg(actor, 1, "客户端版本过旧,请更新后登录")
return false
end
return true
end
---消息路由:按版本分发到对应处理器
function MsgRoute.dispatch(actor, msgId, body)
local ver = actor.protoVer or PROTO_LATEST
local handler = HANDLERS[ver][msgId] or HANDLERS[PROTO_LATEST][msgId]
if handler then
handler(actor, body)
end
end
登录握手时客户端上报协议版本,服务器校验版本在支持列表内才放行。消息的路由按版本两级查找:先查版本专属处理器,缺省回落到最新版处理器——旧客户端没用到的新消息在旧表里查不到,回落逻辑让新增消息零成本兼容。支持窗口收敛:同时最多支持两个版本,强更推进时旧版本的支持截止日写进公告。
---字段只增不删:旧字段保留填充默认值
function MsgRoute.packRole(actor)
local r = { name = actor:GetName(), level = actor:GetLevel() }
if actor.protoVer < 20 then
-- v20 以下没有新字段,补默认值
r.title = ""
r.fashion = 0
else
r.title = actor:GetTitle()
r.fashion = actor:GetFashion()
end
return r
end
字段变更的三条纪律:只增不删、新增字段带默认值语义(旧客户端不认识就当没有)、语义变更必须换新号不复用——旧号的消息含义变了,两版客户端的默契就崩了。裁决之杖在新版本换了贴图编号,旧客户端按旧编号渲染,图标字段做映射表让两版各自取所需。服务器的日志按版本维度统计在线占比,旧版本占比降到 1% 以下即下线兼容代码,兼容的债有还清的日子。
双版本并行的兼容性测试矩阵:每条消息在两个版本下的收发用例自动跑,覆盖率要求 100%;按版本拆分的错误率监控,某版本错误率异常升高即为兼容回归。
版本号曾经只在登录时读一次,热更新后版本变了服务器不知情,版本随每次会话鉴权刷新。新增字段曾经直接塞进共享结构,旧客户端解析到未知字段直接崩,按版本分支序列化后修复。两版的消息号曾经撞号,新功能复用了废弃号,协议号的分配表统一管理。
协议变更的评审流程:每个号段的变更记录进协议文档,评审通过才分配。强更与共存的选择标准写明:安全类修复强更、内容类更新共存。兼容代码的下线与版本支持的截止同步,公告提前两周预告。
本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 全服 400 多个 NPC 脚本在开服瞬间集中加载,引擎进程启动耗时 47 秒,值班期间重启就是 47 …
实战应用:用在哪里 行会跨图集合靠世界喊话,从比奇赶到沙巴克动辄三分钟,集合效率低。行会驿站给每个行会一个专属传送网络:驿站…
实战应用:用在哪里 跨服战场周日结算夜出了双事故:30 名玩家积分凭空翻倍,随后 12 名玩家积分变成负数。两条线索指向同一…
实战应用:用在哪里 烈火剑法点到一半想换逐日剑法,没有遗忘功能只能养小号,新手加点点废的投诉长期霸榜。技能遗忘与重修框架管三…
实战应用:用在哪里 战斗日志全量滚动,烈火剑法暴击、治疗、拾取一场下来上千条,列表越长滑动越卡。改造分两件事:内存里只留最近…
实战应用:用在哪里 夏季活动缺一个全服参与的轻竞速,选定龙舟:五人一队从白日门河道上游划向盟重码头,河道布设障碍与顺流带,全…