skynet是为多人在线游戏设计的轻量级服务端框架,使用C+Lua开发。skynet的特点是,使用这个框架,太多数情况下只是用lua写代码,很少用c写,这一定程度上提高了项目的开发效率。lua虽然没有C高效,但开发复杂业务却是非常便捷。不过,skynet网上文档很少,所以我就利用一点时间总结skynet相关内容。
# nc 127.0.0.1 8000
Welcome to skynet console
clearcache
OK
如果不了解skynet控制台,可以参考我的这篇文章[1]。
# nc 127.0.0.1 8000
Welcome to skynet console
list
:00000004 snlua cmaster
:00000005 snlua cslave
:00000007 snlua datacenterd
:00000008 snlua service_mgr
:0000000a snlua protoloader
:0000000b snlua console
:0000000c snlua debug_console 8000
:0000000d snlua simpledb
OK
inject :0000000d example/inject_simpledb.lua
local skynet = require "skynet"
require "skynet.manager"
local db = {}
local command = {}
-- 增加了这里
local function test(msg)
print(msg)
end
-- 增加了这里
function command.do_test(msg)
test(msg)
end
skynet.start(function()
skynet.dispatch("lua", function(session, address, cmd, ...)
local f = command[string.upper(cmd)]
if f then
skynet.ret(skynet.pack(f(...)))
else
error(string.format("Unknown command %s", tostring(cmd)))
end
end)
-- 增加了这里
skynet.fork(function()
while true do
skynet.sleep(100)
command.do_test("itest!")
end
end)
skynet.register "SIMPLEDB"
end)
假设以上的 command.do_test 就是我们要热更改掉的函数。那用于inject的lua代码如下:
if not _P then
print("hotfix fail, no _P define")
return
end
print("hotfix begin")
-- 用于获取函数变量
local function get_up(f)
local u = {}
if not f then
return u
end
local i = 1
while true do
local name, value = debug.getupvalue(f, i)
if name == nil then
return u
end
u[name] = value
i = i + 1
end
return u
end
-- 获取原来的函数地址,及函数变量
local command = _P.lua.command
local upvs = get_up(command.do_test)
local test = upvs.test
command.do_test = function(msg)
test('New ' .. msg)
end
print("hotfix end")
# ./skynet examples/config
[:00000001] LAUNCH logger
[:00000002] LAUNCH snlua bootstrap
[:00000003] LAUNCH snlua launcher
[:00000004] LAUNCH snlua cmaster
[:00000005] LAUNCH snlua cslave
[:00000006] LAUNCH harbor 1 16777221
[:00000007] LAUNCH snlua datacenterd
[:00000008] LAUNCH snlua service_mgr
[:00000009] LAUNCH snlua main
[:0000000a] LAUNCH snlua protoloader
[:0000000b] LAUNCH snlua console
[:0000000c] LAUNCH snlua debug_console 8000
[:0000000d] LAUNCH snlua simpledb
[:0000000e] LAUNCH snlua watchdog
[:0000000f] LAUNCH snlua gate
[:0000000f] Listen on 0.0.0.0:8888
Watchdog listen on 8888
[:00000009] KILL self
[:00000002] KILL self
itest!
itest!
itest!
New itest!
New itest!