require("luaScript.Protocol.ProtoDef") local Protocol = class("Protocol" , require("luaScript.Protocol.BindableArray")) function Protocol:ctor(net) -- 协议对应的网络链接 self.net = net; -- 保存模块ID self.ModuleId = 99; -- 已经注册的服务器消息列表 self.PushMsgList = {} cc.GameObject.extend(self) self:addComponent(require("luaScript.cc.components.behavior.EventProtocol"):new()):exportMethods() end -- 记录所有发送消息等待回调的函数列表,当断线重连时 g_regMsgCallBackFuncs = {} --[[ 发送消息,并接收回调 args = { cmd , -- 命令ID sender , -- 可选参数,发送的结构体实例(通过defClass定义的类的new创建出来的实例) reader , -- 可选参数,接收的结构体类型(通过defClass定义) func , -- 可选参数,回调函数,类型是func(statusCode , response),其中response时read结构体读出来的数据 } --]] function Protocol:sendResponse(args) assert(args.cmd ~= nil); -- 检查一下网络是否正常 if not self.net or not self.net:isConnected() then if isWin32Platform() then assert(false); end return end -- 如果定义了需要发送的数据,就发送数据,否则只发命令 if args.sender then args.sender:send(self.ModuleId , args.cmd, self.net); else self.net:sendCmd(self.ModuleId , args.cmd); end local unregFunc = nil local function onMsg(statusCode , stream) -- 清空注册以及清空记录 g_regMsgCallBackFuncs[unregFunc]() g_regMsgCallBackFuncs[unregFunc] = nil if statusCode ~= 0 then args.func(statusCode); print("onMsg时返回了非0 statusCode:" .. tostring(statusCode)); return end if args.reader then local response = args.reader:tryRead(stream); if response then args.func(statusCode , response); else args.func(2); end else args.func(statusCode); end end -- 如果定义了回调函数,则接收数据 if args.func and args.resCmd then assert(type(args.func) == "function") self.net:regMsg(self.ModuleId, args.resCmd, onMsg); unregFunc = function()self.net:unregMsg(onMsg)end g_regMsgCallBackFuncs[unregFunc] = unregFunc end end --[[ 定义网络消息函数,并把这个函数导出到当前Protocol类中对外公开 对外公开的函数定义是name(sendArgs , responseFunc)或name(responseFunc) args = { name , -- 需要导出的函数名称 cmd , -- 命令ID sender , -- 可选参数,发送的结构体类型(通过defClass定义) reader , -- 可选参数,接收的结构体类型(通过defClass定义) func , -- 可选参数,回调函数,类型是func(statusCode , response)或func(statusCode),其中response时read结构体读出来的数据 } --]] function Protocol:defMsgFunc(args) --[[ { name = "", cmd = number, resCmd = number, sender = netClass, reader = netClass, func = function, } ]] assert(args.name ~= nil and type(args.cmd) == "number"); if args.sender then -- sendArgs是一个表,会把这个表的数据拷贝到sender中 local function sendData(self , sendArgs , responseFunc) local args = clone(args); local sender = args.sender:new(); for i , v in pairs(sendArgs) do sender[i] = v; end args.sender = sender; local argFunc = args.func; if argFunc then args.func = function(statusCode , response) argFunc(statusCode , response); if responseFunc then responseFunc(statusCode , response) end end; elseif responseFunc then args.func = responseFunc; end self:sendResponse(args); end self[args.name] = sendData; else local function sendData(self , responseFunc) local args = clone(args); local argFunc = args.func; if argFunc then args.func = function(statusCode , response) argFunc(statusCode , response); if responseFunc then responseFunc(statusCode , response) end end; elseif responseFunc then args.func = responseFunc; end self:sendResponse(args); end self[args.name] = sendData; end end --[[ 定义一个推送消息,会持续地接收这个消息,并通过回调函数返回数据 args = { cmd , -- 命令ID reader , -- 可选参数,接收的结构体类型(通过defClass定义) func , -- 可选参数,回调函数,类型是func(statusCode , response),其中response时read结构体读出来的数据 } --]] function Protocol:defPushMsg(args) assert(args.cmd ~= nil); local function onMsg(statusCode , stream) if statusCode ~= 0 then args.func(statusCode); print("onMsg时返回了非0 statusCode:" .. tostring(statusCode)); return end if args.reader then local response = args.reader:tryRead(stream); if response then args.func(statusCode , response); else args.func(2); end else args.func(statusCode); end end -- 如果定义了回调函数,则接收数据 if args.func then --table.insert(args.cmd, args.func); self.PushMsgList[args.cmd] = onMsg--args.func self.net:regMsg(self.ModuleId, args.cmd, onMsg); end end function Protocol:defPullMsg(args) if args.sender then -- sendArgs是一个表,会把这个表的数据拷贝到sender中 local function sendData(responseFunc) local args = clone(args); local sender = args.sender:new(); args.sender = sender; args.func = responseFunc; self:sendResponse(args); end else local function sendData(responseFunc) local args = clone(args); args.func = responseFunc; self:sendResponse(args); end end self:defMsgFunc(args); end function Protocol:unRegAll() for cmdId,func in pairs(self.PushMsgList) do self.net:unregMsg(func); end end return Protocol;