mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-25 12:43:09 +00:00
snax : a simple skynet auxliliary framework
This commit is contained in:
@@ -7,5 +7,6 @@ master = "127.0.0.1:2013"
|
|||||||
start = "main"
|
start = "main"
|
||||||
standalone = "0.0.0.0:2013"
|
standalone = "0.0.0.0:2013"
|
||||||
luaservice = root.."service/?.lua;"..root.."test/?.lua;"..root.."examples/?.lua"
|
luaservice = root.."service/?.lua;"..root.."test/?.lua;"..root.."examples/?.lua"
|
||||||
|
snax = root.."examples/?.lua;"..root.."test/?.lua"
|
||||||
cpath = root.."cservice/?.so"
|
cpath = root.."cservice/?.so"
|
||||||
redis = root .. "examples/redisconf"
|
redis = root .. "examples/redisconf"
|
||||||
|
|||||||
98
lualib/snax.lua
Normal file
98
lualib/snax.lua
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
local skynet = require "skynet"
|
||||||
|
local snax_interface = require "snax_interface"
|
||||||
|
|
||||||
|
local snax = {}
|
||||||
|
local typeclass = {}
|
||||||
|
|
||||||
|
local G = { require = function() end }
|
||||||
|
|
||||||
|
function snax.interface(name)
|
||||||
|
if typeclass[name] then
|
||||||
|
return typeclass[name]
|
||||||
|
end
|
||||||
|
|
||||||
|
local si = snax_interface(name, G)
|
||||||
|
|
||||||
|
local ret = {
|
||||||
|
subscribe = {},
|
||||||
|
response = {},
|
||||||
|
system = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _,v in ipairs(si) do
|
||||||
|
local id, group, name, f = table.unpack(v)
|
||||||
|
if group == "system" then
|
||||||
|
if f then
|
||||||
|
ret.system[name] = id
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ret[group][name] = id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
typeclass[name] = ret
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
local meta = { __tostring = function(v) return string.format("[%s:%x]", v.type, v.handle) end}
|
||||||
|
|
||||||
|
local skynet_send = skynet.send
|
||||||
|
local skynet_call = skynet.call
|
||||||
|
|
||||||
|
local function gen_pub(type, handle)
|
||||||
|
return setmetatable({} , {
|
||||||
|
__index = function( t, k )
|
||||||
|
local id = assert(type.subscribe[k] , string.format("publish %s no exist", k))
|
||||||
|
return function(...)
|
||||||
|
skynet_send(handle, "lua", id, ...)
|
||||||
|
end
|
||||||
|
end })
|
||||||
|
end
|
||||||
|
|
||||||
|
local function gen_req(type, handle)
|
||||||
|
return setmetatable({} , {
|
||||||
|
__index = function( t, k )
|
||||||
|
local id = assert(type.response[k] , string.format("request %s no exist", k))
|
||||||
|
return function(...)
|
||||||
|
return skynet_call(handle, "lua", id, ...)
|
||||||
|
end
|
||||||
|
end })
|
||||||
|
end
|
||||||
|
|
||||||
|
local function wrapper(handle, name, type)
|
||||||
|
return setmetatable ({
|
||||||
|
pub = gen_pub(type, handle),
|
||||||
|
req = gen_req(type, handle),
|
||||||
|
type = name,
|
||||||
|
handle = handle,
|
||||||
|
kill = function(...) return skynet_call(handle, "lua", type.system.exit, ...) end,
|
||||||
|
}, meta)
|
||||||
|
end
|
||||||
|
|
||||||
|
local handle_cache = setmetatable( {} , { __mode = "kv" } )
|
||||||
|
|
||||||
|
function snax.newservice(name, ...)
|
||||||
|
local t = snax.interface(name)
|
||||||
|
local handle = skynet.newservice("snaxd", name)
|
||||||
|
assert(handle_cache[handle] == nil)
|
||||||
|
if t.system.init then
|
||||||
|
skynet.call(handle, "lua", t.system.init, ...)
|
||||||
|
end
|
||||||
|
local ret = wrapper(handle, name, t)
|
||||||
|
handle_cache[handle] = ret
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
function snax.bind(handle, type)
|
||||||
|
local ret = handle_cache[handle]
|
||||||
|
if ret then
|
||||||
|
assert(ret.type == type)
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
local t = snax.interface(type)
|
||||||
|
ret = wrapper(handle, type, t)
|
||||||
|
handle_cache[handle] = ret
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
return snax
|
||||||
84
lualib/snax_interface.lua
Normal file
84
lualib/snax_interface.lua
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
local skynet = require "skynet"
|
||||||
|
|
||||||
|
return function (name , G)
|
||||||
|
local mainfunc
|
||||||
|
|
||||||
|
local function func_id(id, group)
|
||||||
|
local tmp = {}
|
||||||
|
local function count( _, name, func)
|
||||||
|
if type(name) ~= "string" then
|
||||||
|
error (string.format("%s method only support string", group))
|
||||||
|
end
|
||||||
|
if type(func) ~= "function" then
|
||||||
|
error (string.format("%s.%s must be function"), group, name)
|
||||||
|
end
|
||||||
|
if tmp[name] then
|
||||||
|
error (string.format("%s.%s duplicate definition", group, name))
|
||||||
|
end
|
||||||
|
tmp[name] = true
|
||||||
|
table.insert(id, { #id + 1, group, name, func} )
|
||||||
|
end
|
||||||
|
return setmetatable({}, { __newindex = count })
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
assert(getmetatable(G) == nil)
|
||||||
|
assert(G.init == nil)
|
||||||
|
assert(G.exit == nil)
|
||||||
|
|
||||||
|
assert(G.subscribe == nil)
|
||||||
|
assert(G.response == nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
local env = {}
|
||||||
|
local func = {}
|
||||||
|
|
||||||
|
local system = { "init", "exit" }
|
||||||
|
|
||||||
|
do
|
||||||
|
for k, v in ipairs(system) do
|
||||||
|
system[v] = k
|
||||||
|
func[k] = { k , "system", v }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
env.subscribe = func_id(func, "subscribe")
|
||||||
|
env.response = func_id(func, "response")
|
||||||
|
|
||||||
|
local function init_system(t, name, f)
|
||||||
|
local index = assert(system[name] , string.format("Not support global var %s", name))
|
||||||
|
if type(f) ~= "function" then
|
||||||
|
error (string.format("%s must be a function", name))
|
||||||
|
end
|
||||||
|
func[index][4] = f
|
||||||
|
end
|
||||||
|
|
||||||
|
setmetatable(G, { __index = env , __newindex = init_system })
|
||||||
|
|
||||||
|
do
|
||||||
|
local path = skynet.getenv "snax"
|
||||||
|
|
||||||
|
local errlist = {}
|
||||||
|
|
||||||
|
for pat in string.gmatch(path,"[^;]+") do
|
||||||
|
local filename = string.gsub(pat, "?", name)
|
||||||
|
local f , err = loadfile(filename, "bt", G)
|
||||||
|
if f then
|
||||||
|
mainfunc = f
|
||||||
|
break
|
||||||
|
else
|
||||||
|
table.insert(errlist, err)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if mainfunc == nil then
|
||||||
|
error(table.concat(errlist, "\n"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
mainfunc()
|
||||||
|
|
||||||
|
setmetatable(G, nil)
|
||||||
|
|
||||||
|
return func
|
||||||
|
end
|
||||||
33
service/snaxd.lua
Normal file
33
service/snaxd.lua
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
local skynet = require "skynet"
|
||||||
|
local snax_interface = require "snax_interface"
|
||||||
|
|
||||||
|
local func = snax_interface(tostring(...), _ENV)
|
||||||
|
|
||||||
|
skynet.start(function()
|
||||||
|
local init = false
|
||||||
|
skynet.dispatch("lua", function ( _, _, id, ...)
|
||||||
|
local method = func[id]
|
||||||
|
if method[2] == "system" then
|
||||||
|
if method[3] == "init" then
|
||||||
|
assert(not init, "Already init")
|
||||||
|
local initfunc = method[4] or function() end
|
||||||
|
skynet.ret(skynet.pack(initfunc(...)))
|
||||||
|
init = true
|
||||||
|
else
|
||||||
|
assert(init, "Never init")
|
||||||
|
local exitfunc = method[4] or function() end
|
||||||
|
skynet.ret(skynet.pack(exitfunc(...)))
|
||||||
|
init = false
|
||||||
|
skynet.exit()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
assert(init, "Init first")
|
||||||
|
if method[2] == "subscribe" then
|
||||||
|
-- no return
|
||||||
|
method[4](...)
|
||||||
|
else
|
||||||
|
skynet.ret(skynet.pack(method[4](...)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end)
|
||||||
@@ -1,27 +1,23 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
|
|
||||||
local command = {}
|
function response.ping(hello)
|
||||||
|
skynet.sleep(100)
|
||||||
function command.PING(hello)
|
|
||||||
return hello
|
return hello
|
||||||
end
|
end
|
||||||
|
|
||||||
function command.HELLO()
|
function subscribe.hello()
|
||||||
skynet.sleep(100)
|
print "hello"
|
||||||
return "hello"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function command.EXIT()
|
function response.error()
|
||||||
skynet.exit()
|
|
||||||
end
|
|
||||||
|
|
||||||
function command.ERROR()
|
|
||||||
error "throw an error"
|
error "throw an error"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function init( ... )
|
||||||
|
print ("ping server start:", ...)
|
||||||
|
end
|
||||||
|
|
||||||
skynet.start(function()
|
function exit(...)
|
||||||
skynet.dispatch("lua", function(session,addr, cmd, ...)
|
print ("ping server exit:", ...)
|
||||||
skynet.ret(skynet.pack(command[cmd](...)))
|
return "Exit"
|
||||||
end)
|
end
|
||||||
end)
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
local skynet = require "skynet"
|
local skynet = require "skynet"
|
||||||
|
local snax = require "snax"
|
||||||
|
|
||||||
skynet.start(function()
|
skynet.start(function()
|
||||||
local ps = skynet.uniqueservice("pingserver")
|
local ps = snax.newservice ("pingserver", "hello world")
|
||||||
skynet.watch(ps)
|
print(ps.pub.hello())
|
||||||
print(pcall(skynet.call,ps,"lua","ERROR"))
|
print(ps.req.ping("foobar"))
|
||||||
print(skynet.call(ps, "lua", "PING", "hello"))
|
print(pcall(ps.req.error))
|
||||||
print(skynet.call(ps, "lua", "PING", "hay"))
|
print(ps.kill("exit"))
|
||||||
skynet.call(ps, "lua", "EXIT")
|
skynet.exit()
|
||||||
end)
|
end)
|
||||||
|
|||||||
Reference in New Issue
Block a user