skynet Sproto 使用解析

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) 服务器发送数据给客户端

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值