|
- NetBase = class("NetBase");
-
- NetClientState =
- {
- Disconnect = 0,
- Connectting = 1,
- Connected = 2,
- }
-
- local function gettable(tab , key , defaultValue)
- local value = tab[key];
- if value then
- return value
- else
- value = defaultValue
- tab[key] = value
- return value
- end
- end
-
- local function NetworkFuncGet(self , moduleID)
- return gettable(self, moduleID, {
- get = function(self , cmdID)
- return gettable(self, cmdID, {
- funcs = {},
- callbacks = {},
- dirty = true,
- insert = function(self , func)
- self.funcs[func] = 1
- self.dirty = true
- end,
- remove = function(self , func)
- self.funcs[func] = nil
- self.dirty = true
- end,
- })
- end,
- })
- end
-
- -- 构造函数
- function NetBase:ctor()
- -- 保存(模块->命令->函数)的对应关系
- self.mNetworkFunc = {}
- -- 保存(函数->模块、命令)的对应关系
- self.mFuncToCmd = {}
-
- self.mNetworkFunc.get = NetworkFuncGet
-
- -- 初始状态下是不需要重连的
- -- 第一次成功链接后才设置为需要重连
- -- 再往后可以根据需要修改
- self.isNeedReconnect = false
-
- -- 游戏切换到后台之后缓存的服务器消息,
- -- 切换回来之后手动发送一遍
- self.isBackGround = false;
- self.netMessageStack = {}
- app:addEventListener("applicationDidEnterBackground", handler(self,self.onApplicationDidEnterBackground))
- app:addEventListener("applicationWillEnterForeground", handler(self, self.onApplicationWillEnterForeground))
- end
-
- -- 需重写:连接时的回调
- function NetBase:OnConnecttingCallback()
-
- end
-
- -- 需重写:连接成功之后的回调
- function NetBase:OnConnectedCallback()
-
- end
-
- -- 需重写:断开连接时的回调
- function NetBase:OnDisconnectCallback()
-
- end
-
- -- 是否处于链接状态
- function NetBase:isConnected()
- if self.Socket then
- return self.Socket:state() == NetClientState.Connected;
- else
- return false
- end
- end
-
- --
- function NetBase:isInited()
- return self.Socket ~= nil;
- end
-
-
- function NetBase:onRecvServerMsg(moduleID , cmdID , statusCode , stream)
-
- end
-
-
- --------------------------------------------------------------------------------------
- --------------------------------------------------------------------------------------
- --------------------------------------------------------------------------------------
- --------------------------------------------------------------------------------------
-
-
- -- 注册一个网络消息回调
- function NetBase:regMsg(moduleID , cmdID , func)
- if type(func) ~= "function" then
- error("regMsg时传入了不正确的function,moduleID[" .. tostring(moduleID) .. "] cmdID[" .. tostring(cmdID) .. "] func[" .. tostring(func) .. "]");
- return
- end
- self.mNetworkFunc:get(moduleID):get(cmdID):insert(func);
- self.mFuncToCmd[func] = {moduleID,cmdID};
- end
-
- -- 反注册一个网络消息
- function NetBase:unregMsg(func)
- if type(func) ~= "function" then
- error("unregMsg时传进来的第一个参数不是function");
- end
- local funcToCmd = self.mFuncToCmd[func];
- if funcToCmd == nil then
- return
- end
- self.mNetworkFunc:get(funcToCmd[1]):get(funcToCmd[2]):remove(func);
- self.mFuncToCmd[func] = nil;
- end
-
- -- 通过命令ID移除网络消息监听
- function NetBase:removeMsgHandler(cmdID)
- for func,funcToCmd in pairs(self.mFuncToCmd) do
- if funcToCmd[2]==cmdID then
- self:unregMsg(func)
- end
- end
- end
-
- -- 发送消息到服务器
- function NetBase:send(moduleID , cmdID , stream)
- print(string.format("发送消息:moduleID[%d] cmdID[%#x] size[%d]", moduleID, cmdID, NetStream.getWriteSize(stream)));
- -- 如果网络已经断开,则果断提示错误
- if self.Socket:state() ~= NetClientState.Connected then
- --NetStream.delete(stream)
- showTooltip("网络已断开");
- return;
- end
- self.Socket:send(moduleID , cmdID , stream)
- end
-
- -- 发送一个命令(不带用户数据)到服务器
- function NetBase:sendCmd(moduleID , cmdID)
- local stream = NetStream.new();
- self:send(moduleID , cmdID , stream);
- NetStream.delete(stream)
- end
-
- -- 网络消息处理函数
- function NetBase:onNetworkMsg(moduleID , cmdID , statusCode , stream)
- if statusCode ~= 0 then
- --showTooltip("statusCode = "..statusCode);
- print(string.format("接受消息:moduleID[%d] cmdID[%#x] statusCode[%d]", moduleID, cmdID, statusCode));
- else
- print(string.format("接受消息:moduleID[%d] cmdID[%#x] statusCode[%d] size[%d]", moduleID, cmdID, statusCode, NetStream.getReadSize(stream)));
- end
-
- local mod = self.mNetworkFunc[moduleID];
- if mod then
- local cmd = mod[cmdID];
- if cmd then
- if cmd.dirty then
- cmd.dirty = false
- cmd.callbacks = {}
- for i,v in pairs(cmd.funcs) do
- cmd.callbacks[i] = v
- end
- end
- local funcs = cmd.callbacks
- for func,v in pairs(funcs) do
- NetStream.reset(stream);
- func(statusCode , stream);
- end
- if cmd.dirty then
- cmd.callbacks = {}
- end
- end
- end
- end
-
- -- 开始连接
- function NetBase:connect(ip, port)
-
- log("moduleID[99] - NetBase:connect() ")
-
- if self.Socket and self.Socket:state() == NetClientState.Connectting then
- --showTooltip("moduleID[99] - is Connectting, return")
- return;
- end
-
- -- 处理 socket 状态变化
- local function onState(state)
- log("NetBase::connect() onState() state = ", tostring(state))
-
- if state == NetClientState.Connectting then
- log("moduleID[99] - Connectting")
- self:OnConnecttingCallback()
- elseif state == NetClientState.Connected then
- log("moduleID[99] - Connected")
- -- self:closeTimer();
- app.waitDialogManager:closeWaitNetworkDialog()
- self:OnConnectedCallback()
- elseif state == NetClientState.Disconnect then
- log("moduleID[99] - Disconnect")
- -- self:closeTimer();
- app.waitDialogManager:closeWaitNetworkDialog()
- self:OnDisconnectCallback()
- end
- end
-
- -- 处理服务器消息
- local function onMessage(moduleID , cmdID , statusCode , stream)
- -- 如果游戏退入后台,则拦截所有除心跳之外的消息
- -- 回来的时候再轮流处理
- if self.isPause and cmdID ~= 0x2008 then
- local streamData = NetStream.getReadData(stream);
- local newStream = NetStream.new(streamData);
- table.insert(self.netMessageStack, {moduleID=moduleID, cmdID=cmdID , statusCode=statusCode , stream=newStream})
- else
- self:onNetworkMsg(moduleID , cmdID , statusCode , stream)
- self:onRecvServerMsg(moduleID , cmdID , statusCode , stream)
- end
- end
- if not self.Socket then
- self.Socket = NetClient.new(onMessage , onState);
-
- -- 网宿水印
- local setting = require("luaScript.Config.Setting")
- if setting and setting.NetClientParams then
- local v = setting.NetClientParams
- local num = #setting.NetClientParams
- if num == 5 then
- self.Socket:setParams(v[1], v[2], v[3], v[4], v[5])
- end
- end
-
- local timeOut = 5;
- if isIOSReviewVersion() then
- timeOut = 30;
- end
- if self.Socket.setConnectTimeout then
- self.Socket:setConnectTimeout(timeOut)
- end
- if self.Socket.setWriteTimeout then
- self.Socket:setWriteTimeout(timeOut)
- end
- if self.Socket.setReadTimeout then
- self.Socket:setReadTimeout(timeOut)
- end
- end
-
- -- 记录当前使用的ip和端口
- self.ip = ip;
- self.port = port;
- if not ip or not port then
- showTooltip("无效的 ip 或 port");
- return;
- end
-
- -- 连接网络
- app.waitDialogManager:showWaitNetworkDialog("登录中....")
- -- self:startTimer();
-
- if isDebug() then
- showTooltip("尝试链接 "..ip.." : "..port)
- end
-
- log("尝试链接 "..ip.." : "..port)
-
- self.netMessageStack = {}
-
- getHostAndIpByUrl(ip, function(host2, ip2)
- if ip2 then
- self.Socket:connect(ip2, port)
- else
- self.Socket:connect(ip, port)
- end
- end)
- end
-
- -- 断开连接
- function NetBase:close()
- log("200000 moduleID[99] NetBase:close()")
- if self.Socket then
- self.Socket:close();
- end
- end
-
- -- 开始连接后启动计时器,指定的时间没有连接上,记为超时
- function NetBase:startTimer()
- log("moduleID[99] NetBase:startTimer()");
- local function outTimeCallback()
- log("moduleID[99] NetBase:startTimer() outTimeCallback()");
- self:close()
- end
-
- -- 先关闭,再创建
- self:closeTimer()
-
- local timeOut = getNetTimeOutNum();
- log("moduleID[99] NetBase:startTimer() timeOut = ", tostring(timeOut));
-
- self.scheduleHandle = cc.Director:getInstance():getScheduler():scheduleScriptFunc(outTimeCallback, timeOut, false);
- log("moduleID[99] NetBase:startTimer() scheduleHandle = ", tostring(self.scheduleHandle));
- end
-
- function NetBase:closeTimer()
- log("moduleID[99] NetBase:closeTimer()");
-
- if self.scheduleHandle then
- log("moduleID[99] NetBase:closeTimer() unscheduleScriptEntry ", tostring(self.scheduleHandle));
- cc.Director:getInstance():getScheduler():unscheduleScriptEntry(self.scheduleHandle);
- self.scheduleHandle = nil;
- else
- log("moduleID[99] NetBase:closeTimer() scheduleHandle is nil");
- end
- end
-
- function NetBase:onApplicationDidEnterBackground()
- self:onMsgPause()
- end
-
- function NetBase:onApplicationWillEnterForeground()
- self:onMsgResume();
- end
-
- function NetBase:onMsgPause()
- log("moduleID[99] NetBase:onMsgPause")
- self.isPause = true
- end
-
- function NetBase:onMsgResume()
- log("moduleID[99] NetBase:onMsgResume")
- if self.netMessageStack and #self.netMessageStack > 0 then
- app:dispatchEvent({name = "onDealMessageStackBegin" , net = self});
- for k,v in ipairs(self.netMessageStack) do
- self:onNetworkMsg(v.moduleID , v.cmdID, v.statusCode , v.stream)
- self:onRecvServerMsg(v.moduleID , v.cmdID, v.statusCode , v.stream)
- NetStream.delete(v.stream);
- end
- app:dispatchEvent({name = "onDealMessageStackEnd" , net = self});
- end
- self:onMsgClear();
- self.isPause = false
- end
-
-
- function NetBase:onMsgResumeEx()
- self.isPause=false
- while #self.netMessageStack > 0 do
- if self.isPause then
- return
- end
- self:runNextMsg()
- end
- end
-
- function NetBase:runNextMsg()
- log("NetBase:runNextMsg")
- if self.netMessageStack and #self.netMessageStack > 0 then
- local v = self.netMessageStack[1]
- table.remove(self.netMessageStack,1)
- self:onNetworkMsg(v.moduleID , v.cmdID, v.statusCode , v.stream)
- self:onRecvServerMsg(v.moduleID , v.cmdID, v.statusCode , v.stream)
- NetStream.delete(v.stream)
- return true
- end
- return false
- end
-
- function NetBase:onMsgClear()
- self.netMessageStack = {}
- end
-
- return NetBase;
|