local _M = { } -- 超时次数 local heartTimeoutCount = 0 -- 加速次数 local heartQuickCount = 0 -- 上次检查心跳时间 local lastHeartCheckTime = 0 -- 下次进入定时检查的时间 local nextCheckTime = 0 -- 心跳误差允许范围 local HEART_BEAT_ERROR_LIMIT = 1 -- 最大超时次数 local HEART_TIMEOUT_COUNT_MAX = 20 -- 最大加速次数 local HEART_QUICK_COUNT_MAX = 5 -- 心跳定时间隔 local HEART_TIMER_INTERVAL = 5 local function check_heart_beat(agent, now) -- 充值等操作不检查心跳 local role = agent.role if role.ignoreHeartbeat then lastHeartCheckTime = now - HEART_TIMER_INTERVAL heartTimeoutCount = 0 return end if lastHeartCheckTime - now > HEART_TIMER_INTERVAL or now - lastHeartCheckTime > HEART_TIMER_INTERVAL then heartTimeoutCount = heartTimeoutCount + 1 if heartTimeoutCount >= HEART_TIMEOUT_COUNT_MAX then skynet.error("timeout! then agent will shut down by self", agent.client_fd, role:getProperty("name"), role:getProperty("id")) skynet.call(agent.gate_serv, "lua", "kick", agent.client_fd) heartTimeoutCount = 0 end else heartTimeoutCount = 0 end end function _M:update(agent) local now = skynet.timex() local role = agent.role if now >= nextCheckTime then pcall(check_heart_beat, agent, now) nextCheckTime = now + HEART_TIMER_INTERVAL end pcall(role.onRecoverTimer, role, now) end function _M:heart_beat(agent) local now = skynet.timex() if now == lastHeartCheckTime then return end if now - lastHeartCheckTime <= HEART_TIMER_INTERVAL - HEART_BEAT_ERROR_LIMIT then heartQuickCount = heartQuickCount + 1 if heartQuickCount == HEART_QUICK_COUNT_MAX then -- 将错误写入日志 local role = agent.role skynet.error("Warning, heart beating is too quick, shut down the agent", agent.client_fd, role:getProperty("name"), role:getProperty("id")) -- skynet.call(agent.gate_serv, "lua", "kick", agent.client_fd) role:warningHeartTooQuick() heartQuickCount = 0 end else heartQuickCount = 0 end lastHeartCheckTime = now end function _M:reset() heartTimeoutCount = 0 heartQuickCount = 0 lastHeartCheckTime = skynet.timex() end return _M