skynet因为require有缓存,不能像如下方式热更:
package.loaded[module] = nil
require(module)
虽然可以如下这样清下缓存:
local cache = require "skynet.codecache"
cache.clear()
但是这样的成本比较大。只更新一个脚本,却把所有脚本的缓存清了。
skynet的DebugConsole服务提供一个更新service的方法:inject。
inject address script 将 script 名字对应的脚本插入到指定服务中运行(通常可用于热更新补丁)。
其原理就是修改skynet.dispatch的upvalue,如
--我们的服务里
skynet.dispatch("lua", function(session, source, cmd,...)
local f = assert(CMD[cmd])
skynet.ret(skynet.pack(f(...)))
end)
我们就可以修改CMD。如下面的patch.lua脚本:
local CMD = _P.lua.CMD
CMD.test = function()
print('new')
end
如果需要更通用的热更方式可以参考云风的
如何让 lua 做尽量正确的热更新
如果模块添加约束条件,没有初始化程序,可以参考:jinq0123/hotfix