protoloader.lua 服务加载 协议内容
skynet.start(function()
sprotoloader.save(proto.c2s, 1)
sprotoloader.save(proto.s2c, 2)
-- don't call skynet.exit() , because sproto.core may unload and the global slot become invalid
end)
协议的使用:
local host = sprotoloader.load(1):host( "package")
local pack = host:attach(sprotoloader.load(2))
sprotoloader.load 的方放获取需要使用的协议索引: 1/2
sprotoloader 中 load 和 save 的原型
function loader.save(bin, index)
local sp = core.newproto(bin)
core.saveproto(sp, index)
end
function loader.load(index)
local sp = core.loadproto(index)
-- no __gc in metatable
return sproto.sharenew(sp)
end
通过调用 C库 core 来实现协议的 加载/获取
loader.load 中 return sproto.sharenew(sp) 将协议内容传递给了lua脚本 sproto.lua。
local sproto_nogc = { __index = sproto }
function sproto.sharenew(cobj)
local self = {
__cobj = cobj,
__tcache = setmetatable( {} , weak_mt ),
__pcache = setmetatable( {} , weak_mt ),
}
return setmetatable(self, sproto_nogc)
end
从本段代码分析:loader.load(index) 最后返回的内容。
在协议的使用过程中调用了 :host( “package”) 实际是 sproto.lua 中的:
function sproto:host( packagename )
packagename = packagename or "package"
local obj = {
__proto = self,
__package = assert(core.querytype(self.__cobj, packagename), "type package not found"),
__session = {},
}
return setmetatable(obj, host_mt)
end
该方法,将 host_mt 设置未 obj 的元方法 host_mt = { __index = host } 该方法其实将host,
host 中包含:
function host:dispatch(...)
local bin = core.unpack(...)
header_tmp.type = nil
header_tmp.session = nil
header_tmp.ud = nil
local header, size = core.decode(self.__package, bin, header_tmp)
local content = bin:sub(size + 1)
if header.type then
-- request
local proto = queryproto(self.__proto, header.type)
local result
if proto.request then
result = core.decode(proto.request, content)
end
if header_tmp.session then
return "REQUEST", proto.name, result, gen_response(self, proto.response, header_tmp.session), header.ud
else
return "REQUEST", proto.name, result, nil, header.ud
end
else
-- response
local session = assert(header_tmp.session, "session not found")
local response = assert(self.__session[session], "Unknown session")
self.__session[session] = nil
if response == true then
return "RESPONSE", session, nil, header.ud
else
local result = core.decode(response, content)
return "RESPONSE", session, result, header.ud
end
end
end
function host:attach(sp)
return function(name, args, session, ud)
local proto = queryproto(sp, name)
header_tmp.type = proto.tag
header_tmp.session = session
header_tmp.ud = ud
local header = core.encode(self.__package, header_tmp)
if session then
self.__session[session] = proto.response or true
end
if proto.request then
local content = core.encode(proto.request, args)
return core.pack(header .. content)
else
return core.pack(header)
end
end
end
host:dispatch(…) 客户端请求,解析。
host:attach(sp) 服务器发送数据给客户端