diff --git a/src/actions/GmAction.lua b/src/actions/GmAction.lua index 711f181..5712e47 100644 --- a/src/actions/GmAction.lua +++ b/src/actions/GmAction.lua @@ -15,6 +15,9 @@ function _M.clientRequest(agent, data) return true end +function _M.testhotfix(role, pms) + return csvdb["itemCsv"][1]["name"] +end function _M.hero(role, pms) local heroType = tonum(pms.pm1) diff --git a/src/actions/HttpAction.lua b/src/actions/HttpAction.lua index 5cfcba9..e634dc0 100644 --- a/src/actions/HttpAction.lua +++ b/src/actions/HttpAction.lua @@ -5,61 +5,64 @@ local codecache = require "skynet.codecache" -- 清空缓存用 local _M = {} --- 清空代码和csvdata 缓存 (无论什么热更新 都要先更新服务器 然后调用这个 api 再进行更新) +-- 清空缓存 function _M.clearcache(query, body) skynet.error(string.format("clearcache time: %s", skynet.timex())) codecache.clear() return 'success' end ---重新加载 csvdata -- 需要先调用 clearcache +--重新加载 需要修改的csvdb +--[=[ eg: + body = """ + csvdb["itemCsv"][1]["name"] = "测试一下" + """ +]=] + function _M.reload_csvdata(query, body) - skynet.error(string.format("reload_csvdata time: %s", skynet.timex())) - local status = skynet.call('CSVDATA', "lua", "reload") - if status == "ok" then - -- 所有需要 更新的服务 都更新一下数据 - pcall(skynet.call, 'WATCHDOG', "lua", "reloadCsvData") - pcall(skynet.call, 'NGXD', "lua", "reloadCsvdb") + if not body or body == "" then + return end - return 'success' -end ---post 需要更改的 globalCsv json -function _M.global_csv(query, body) - if not body or body == "" then return end - local change = json.decode(body) -- json 表 - if not next(change) then return end - skynet.error(string.format("global_csv change time: %s, value: %s", skynet.timex(), body)) - -- 更新所有需要更新globalDefine 的地方 - pcall(skynet.call, 'WATCHDOG', "lua", "reloadCsvData", change) - pcall(skynet.call, 'NGXD', "lua", "reloadCsvdb", change) -- 他也要改 + local ok = pcall(load, body) + if not ok then return end - return 'success' + skynet.error(string.format("reload_csvdata time: %s, code: %s", skynet.timex(), body)) + + local status = skynet.call('CSVDATA', "lua", "reload", body) + if status == "ok" then + return 'success' + end end -- 热更新代码 -- 针对 agent 执行发送过来的代码 -- 代码要规范~ --[=[ eg: -1. *Action 重新加载 (action 每次用才require 直接清掉重新加载) (某些) - body = "package.loaded['actions.*Action']=nil" +1. *Action + body = """ + _hotfixActions = _hotfixActions or {} + _hotfixActions["Gm.clientRequest"] = function(agent, data) + bin = MsgPack.pack({ cmd = "testtest" }) + SendPacket(actionCodes.Gm_receiveResponse, bin) + end + """ 2. 修改 global 方法 和 变量 直接覆盖 body = """ function a() print(123) end + + globalCsv["asdasd"] = 12 + + HEHE = 123 """ -3. 修改 role 方法 +3. 修改 role 方法(待定) body = """ - local role = ... - if role then - role.getItemCount = function(self) - return "hehe" - end - end + """ ]=] @@ -67,9 +70,11 @@ function _M.hotfix(query, body) if not body or body == "" then return end - skynet.error(string.format("hotfix time: %s, code: %s", skynet.timex(), body)) local ok = pcall(load, body) if not ok then return end + + skynet.error(string.format("hotfix time: %s, code: %s", skynet.timex(), body)) + pcall(skynet.call, 'WATCHDOG', "lua", "hotfix", body) return 'success' end diff --git a/src/agent.lua b/src/agent.lua index 7dd7c0c..803dc18 100644 --- a/src/agent.lua +++ b/src/agent.lua @@ -16,12 +16,15 @@ skynet = require "skynet" redisproxy = require "shared.redisproxy" datacenter = require "skynet.datacenter" mcast_util = require "services/mcast_util" +globalCsv = require "csvdata/GlobalDefine" local CMD = {} local agentInfo = {} -- { client_fd, role, gate_serv, open_timer} local agent_util, cs +_hotfixActions = _hotfixActions or {} + --- {{{ 定时器相关 local function handle_timeout() if not agentInfo.open_timer then return end @@ -183,16 +186,21 @@ skynet.register_protocol { print("actionName not exist", actionName) return end - local modName, funcName = actionName:match("(%w+)%.(%w+)") - local ok, action = pcall(require, "actions." .. modName .. "Action") - if not ok then - print("require module name error", action, modName) - return + local method + if _hotfixActions[actionName] then + method = _hotfixActions[actionName] + else + local modName, funcName = actionName:match("(%w+)%.(%w+)") + + local ok, action = pcall(require, "actions." .. modName .. "Action") + if not ok then + print("require module name error", action, modName) + return + end + method = action[funcName] end - - local method = action[funcName] - + if type(method) ~= "function" then print("ERROR_SERVER_INVALID_ACTION", modName, funcName) return @@ -226,7 +234,7 @@ skynet.register_protocol { } -- function CMD.start(gate, fd, ip) -function CMD.start(session, source, gate, fd, ip) +function CMD.start(session, source, gate, fd, ip, hotfixs) ignoreHeartbeat = false agentInfo.client_fd = fd @@ -236,10 +244,9 @@ function CMD.start(session, source, gate, fd, ip) agent_util:reset() math.randomInit() - - -- 这里加载配表 不然热更新对某些 agent 无效 - csvdb = sharedata.query("csvdata") - globalCsv = require "csvdata/GlobalDefine" + for _, hotfix in ipairs(hotfixs) do + CMD.hotfix(hotfix) + end -- 这里将消息伪装成 watchdog 发出,这样就由 A->B->C->B->A 变成 A->B->C->A skynet.redirect(gate, source, "lua", session, skynet.pack("forward", fd, 0, skynet.self())) @@ -274,20 +281,10 @@ function CMD:usubUnion() agentInfo.userv = nil end -function CMD.reloadCsvdb(globalData) - if globalData then - for k, v in pairs(globalData) do - globalCsv[k] = v - end - else - csvdb = sharedata.query("csvdata") - end -end - function CMD.hotfix(code) local ok, func = pcall(load, code) if ok then - ok = pcall(func, agentInfo.role) + ok = pcall(func) end if not ok then skynet.error("hotfix error by code " .. code) @@ -328,6 +325,7 @@ skynet.start(function() cs = queue() + csvdb = sharedata.query("csvdata") -- 错误码特殊处理 -- todo -- for key, value in pairs(csvdb["sys_codesCsv"]) do diff --git a/src/services/agent_ctrl.lua b/src/services/agent_ctrl.lua index 9412c69..ba395a9 100644 --- a/src/services/agent_ctrl.lua +++ b/src/services/agent_ctrl.lua @@ -132,13 +132,10 @@ function _M:check_agent_status() end end -function _M:reload_csvdata(globalData) - for uid, pack in pairs(self.u2f) do - local agent = get_a(pack) - pcall(skynet.send, agent, "lua", "reloadCsvdb", globalData) - end -end +local hotfixList = {} + function _M:hotfix(code) + table.insert(hotfixList, code) for uid, pack in pairs(self.u2f) do local agent = get_a(pack) pcall(skynet.send, agent, "lua", "hotfix", code) @@ -193,7 +190,7 @@ function _M:query_agent(fd, uid) return end - local ok = pcall(skynet.call, agent, "lua", "start", gate_serv, fd, self.f2i[fd]) + local ok = pcall(skynet.call, agent, "lua", "start", gate_serv, fd, self.f2i[fd], hotfixList) if not ok then self.factory:push(agent) query_agent_response(fd, {ret = "INNER_ERROR"}) diff --git a/src/services/csvdatad.lua b/src/services/csvdatad.lua index 2841835..7016328 100644 --- a/src/services/csvdatad.lua +++ b/src/services/csvdatad.lua @@ -61,19 +61,20 @@ end local CMD = {} -function CMD.reload() +function CMD.reload(code) -- 重新加载 csvdata - csvdb = {} - for k, v in pairs(package.loaded) do - if k:find("csvdata") then - package.loaded[k] = nil - end + csvdb = csvdb or {} + + local ok, func = pcall(load, code) + if ok then + ok = pcall(func) + end + if not ok then + skynet.error("reload_csvdata error by code " .. code) + return 'error' end - require("csvdata.init") - require("csvdata.init_adv") sharedata.update("csvdata", csvdb) - skynet.sleep(1) -- 睡一觉再返回 return 'ok' end diff --git a/src/services/httpweb.lua b/src/services/httpweb.lua index 12e19d7..5bdb29f 100644 --- a/src/services/httpweb.lua +++ b/src/services/httpweb.lua @@ -9,7 +9,7 @@ require "utils.init" local table = table local string = string -local port, watchdog = ... +local port = ... port = tonumber(port) local key = "zhaolu1234dangge" diff --git a/src/services/ngxd.lua b/src/services/ngxd.lua index 9a52901..dd60015 100644 --- a/src/services/ngxd.lua +++ b/src/services/ngxd.lua @@ -93,25 +93,10 @@ local function start() end end -local CMD = {} -function CMD.reloadCsvdb(globalData) - if globalData then - for k, v in pairs(globalData) do - globalCsv[k] = v - end - else - csvdb = sharedata.query("csvdata") - end -end - - local function __init__() skynet.dispatch("lua", function(_,_, command, ...) if command == "start" then skynet.ret(skynet.pack(start(...))) - else - local f = CMD[command] - skynet.ret(skynet.pack(f(...))) end end) diff --git a/src/services/watchdog.lua b/src/services/watchdog.lua index bafb8e6..067f1f0 100644 --- a/src/services/watchdog.lua +++ b/src/services/watchdog.lua @@ -89,10 +89,6 @@ function CMD.forceClose(fd) agent_ctrl:exit_agent(fd) end -function CMD.reloadCsvData(globalData) - agent_ctrl:reload_csvdata(globalData) -end - function CMD.hotfix(code) agent_ctrl:hotfix(code) end -- libgit2 0.21.2