-- 协议解析 辅助 local core = require("sproto.core") local sprotoloader = require "sprotoloader" local root = {} local request = nil local response = nil local HOST = nil local attach = nil -- 更新 function root:update() request = nil response = nil HOST = nil attach = nil end -- 获取请求协议 function root:get_c2s() if request == nil then request = sprotoloader.load(1) end return request end -- 获取回应协议 function root:get_s2c() if response == nil then response = sprotoloader.load(2) end return response end function root:get_host() HOST = HOST or self:get_c2s():host "package" return HOST end function root:host_request() local protoS2C = self:get_s2c() attach = attach or self:get_host():attach(protoS2C) return attach end -- 解码请求包 客户端->服务端 function root:decode_c2s_req(msg, sz) local host = self:get_host() local ok, ptype, name, args, rsp = pcall(host.dispatch, host, msg, sz) if not ok then log.error("decode_c2s_req error type[%s]", ptype) return end return ok, ptype, name, args, rsp end -- 编码回应包 客户端->服务端 function root:encode_c2s_rsp(rsp, res, name, args) local ok, rs = pcall(rsp, res) if not ok then log.error("sproto response error: %s", rs) return end return rs end function root:encode_c2s_rsp_ex(name, res, session, ud) local clientHost = self:get_host() local headerTmp = {type = nil, session = session, ud = ud} local header = core.encode(clientHost.__package, headerTmp) local c2s = self:get_c2s() local ok, content = pcall(c2s.response_encode, c2s, name, res) if not ok then error(string.format("打包协议%s出错 %s", name, content)) return end return core.pack(header .. content) end -- 编码推送包 服务端->客户端 function root:encode_s2c_req(name, args) local ok, data = pcall(self:host_request(), name, args) if not ok then log.error("s2c sproto name[%s] args[%s], error", name, tostring(args)) return end return data end local function queryproto(self, pname) local v = self.__pcache[pname] if not v then local tag, req, resp = core.protocol(self.__cobj, pname) assert(tag, pname .. " not found") if tonumber(pname) then pname, tag = tag, pname end v = { request = req, response = resp, name = pname, tag = tag } self.__pcache[pname] = v self.__pcache[tag] = v end return v end -- 解码客户端请求协议 function root:decode_c2s_req_ex(...) local bin = core.unpack(...) local header_tmp = {} header_tmp.type = nil header_tmp.session = nil header_tmp.ud = nil local clientHost = self:get_host() local header, size = core.decode(clientHost.__package, bin, header_tmp) local content = bin:sub(size + 1) if header.type then -- request local proto = queryproto(clientHost.__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, header.session, header.ud else return "REQUEST", proto.name, result, header.session, header.ud end else -- response local session = assert(header_tmp.session, "session not found") local rsp = assert(clientHost.__session[session], "Unknown session") clientHost.__session[session] = nil if rsp == true then return "RESPONSE", session, nil, header.ud else local result = core.decode(rsp, content) return "RESPONSE", session, result, header.ud end end end return root