活动的倒计时、拍卖的截拍、BUFF 的剩余时间全部依赖时钟:客户端的本地时钟不可信(可改可漂移),服务器时间同步把客户端的表校准到服务器的刻度上。校时的协议设计决定了倒计时的准点率。
---校时协议:请求带客户端时间,响应带服务器时间
function TimeSync.request(actor)
local t0 = os.clock()
SL:SendNetMsg(MSGID.TIME_REQ, math.floor(t0 * 1000), 0, 0, "")
end
---服务器的响应:回传两端的时刻
SL:RegisterLuaNetMsg("TIME_ACK", function(data)
local d = SL:JsonDecode(data)
if not d then return end
local t3 = os.clock() * 1000
-- 单向延迟 = (t3 - t0 - 服务器处理) / 2
local offset = d.serverTime - (d.t0 +
(t3 - d.t0) / 2)
TimeSync.offset = offset
TimeSync.calibrated = true
end)
---业务取时间:本地时间加偏移
function TimeSync.now()
return os.time() * 1000 + (TimeSync.offset or 0)
end
校时的往返测量:客户端记录发出时刻 t0,服务器响应带服务器的时刻,客户端收到时计算往返延迟的一半作为单程延迟——偏移量 = 服务器时刻减去本地的中间点。多次校时取中位数滤掉网络抖动的毛刺,偏移的稳定值就是客户端与服务器钟差的估计。业务侧统一走 TimeSync.now 取「服务器视角的当前时间」,倒计时、冷却、活动窗口的时间基准全部对齐。
---周期校准:每 10 分钟微调一次
setontimerex(120, 600)
function TimeSync.periodic()
TimeSync.request()
end
---倒计时的统一读取:活动剩余时间
function TimeSync.activityLeft(endAt)
local now = TimeSync.now()
return math.max(0, endAt - now)
end
---校准失效的兜底:偏移突变即重校
function TimeSync.checkDrift()
if math.abs(TimeSync.offset -
(TimeSync.lastOffset or TimeSync.offset)) > 2000 then
Ops.alert('时间偏移突变,重新校准')
TimeSync.request()
end
end
校准的周期化保持精度:每 10 分钟一次的微调让漂移无处累积,偏移的突变检测(相邻两次差超 2 秒)触发立即重校——时钟的回拨(改表、休眠唤醒)在突变检测下无所遁形。倒计时的显示统一从 TimeSync.now 推算:活动剩余、拍卖截拍、日常重置的三个倒计时同源同准,玩家看到的每一个秒数都值得信任。校时的成本:10 分钟一次、每次一个小包,带宽的占用可以忽略。
偏移量的分布监控:客户端偏移的中位数应在 500 毫秒内,长尾的偏移来自设备的问题;校准的失效次数统计,突变的频发时段联动网络的质量分析。
偏移的计算曾经忽略单程延迟,弱网下活动倒计时提前了几秒,往返的对称假设修复。校准的结果曾经被休眠唤醒重置,唤醒后立即重校的钩子补上。时间戳的单位曾经在毫秒与秒之间混用,千倍的偏差让倒计时集体清零,单位的统一在协议文档写死。
校时的周期与偏移的告警阈值进配置,竞技类玩法收紧精度。服务器的时间源用 NTP 对齐,服务器的钟是整条链的锚。客户端的改表行为不惩罚只校准,校准的机制天然免疫本地时钟的篡改。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 悬赏捕杀把玩家之间的恩怨变成可托付的系统行为:仇家难以亲自复仇时,花费金条发布悬赏,全服玩家接单击杀目标…
实战应用:用在哪里 策划改表是日常动作,漏填字段、引用了不存在的编号、数值越界这三类问题占了配表故障的绝大多数。等玩家报错再…
实战应用:用在哪里 行会擂台给中小行会提供了固定的对抗出口:挑战方击败守擂方后接管擂台,连胜次数决定每日结算奖励档位。接口层…
实战应用:用在哪里 世界首领战里玩家最关心的是伤害前十名:榜单要求随时插入、随时能按序取出,每来一条伤害记录都重新排序一次太…
实战应用:用在哪里 百人同屏的攻城战里,把每条移动、施法消息广播给全地图是最常见的性能失误。九宫格视野的做法是把地图切成等大…
实战应用:用在哪里 留言板、行会招募语、邮件标题这类字段会被玩家自由填写,并写入角色变量或转发给持久层。拼接式的写法一旦遇到…