local net = require("framework.cc.net.init") local ByteArray = require("framework.cc.utils.ByteArray") require("framework.cc.utils.bit") scnet = {} -- 初始化网络 网络监听 function scnet.init( ) local time = net.SocketTCP.getTime() print("socket time:" .. time) local socket = net.SocketTCP.new() socket:setName("HeroGameTcp") socket:setTickTime(1) socket:setReconnTime(6) socket:setConnFailTime(4) socket:addEventListener(net.SocketTCP.EVENT_DATA, scnet.receive) socket:addEventListener(net.SocketTCP.EVENT_CLOSE, scnet.tcpClose) socket:addEventListener(net.SocketTCP.EVENT_CLOSED, scnet.tcpClosed) socket:addEventListener(net.SocketTCP.EVENT_CONNECTED, scnet.tcpConnected) socket:addEventListener(net.SocketTCP.EVENT_CONNECT_FAILURE, scnet.error) scnet.socket = socket end -- 发送数据 msgid 消息id,data 消息数据 function scnet.send( msgid,data ) local _ba = scnet.encodeData(msgid,data) print("scnet.send _ba",_ba:getLen()) if not _ba then print("发送数据出错了.......",msgid) return end _ba:setPos(1) local byteList = {} local byteCount = 0 -- 取出字节,对字节进行加密 for i=1,#_ba._buf do local tmpBit = string.byte(_ba:readRawByte()) byteCount = byteCount + tmpBit tmpBit = bit.band(tmpBit + 80,255) tmpBit = bit.band(bit.bnot(bit.band(tmpBit,255)),255) byteList[i] = tmpBit end byteCount = byteCount % 256 -- 构造新的字节发送给服务器 local result = ByteArray.new(ByteArray.ENDIAN_BIG) result:writeShort(_ba:getLen() + 3) result:writeByte(byteCount) for i=1,#byteList do result:writeByte(byteList[i]) end scnet.socket:send(result:getPack()) end -- 根据messageid来确定数据格式 function scnet.encodeData( msgid,data ) if msgid then local ba = ByteArray.new(ByteArray.ENDIAN_BIG) local fmt = InfoUtil:getMsgFmt(msgid) ba:writeStringUShort("token") -- 此处为用户token,没有就为"" for i=1,#fmt do scnet.writeData(ba,fmt[i],data) end local baLength = ba:getLen() local bt = ByteArray.new(ByteArray.ENDIAN_BIG) bt:writeShort(baLength + 4) -- 2为message length 2为message type bt:writeShort(msgid) bt:writeBytes(ba) return bt end end -- 接收数据 function scnet.receive( event ) local ba = ByteArray.new(ByteArray.ENDIAN_BIG) ba:writeBuf(event.data) ba:setPos(1) -- 注意有可能出现连包情况 while ba:getAvailable() <= ba:getLen() do scnet.decodeData(ba) if ba:getAvailable() == 0 then break end end end -- 消息解析 function scnet.decodeData( ba ) local len = ba:readShort() -- 读数据总长度 local total = ba:readByte() -- 一个用于验证的数子 local byteList = {} local tmpTotal = 0 for i=1,len - 3 do -- 去除前两个长度 local tmpBit = ba:readByte() local enByte = scnet.decodeByte(tmpBit) tmpTotal = tmpTotal + enByte byteList[i] = enByte end local result = ByteArray.new(ByteArray.ENDIAN_BIG) for i=1,#byteList do result:writeRawByte(string.char(byteList[i])) end result:setPos(1) if (tmpTotal % 256) == total then scnet.decodeMsg(result) else print("scnet.decodeData total error") end end -- 根据格式解析数据 function scnet.decodeMsg( byteArray ) local rData = {} local len = byteArray:readShort() local msgid = byteArray:readShort() local roleString = byteArray:readStringUShort() local fmt = InfoUtil:getMsgFmt(msgid) for i=1,#fmt do scnet.readData(byteArray,fmt[i],rData) end if rData["result"] ~= 0 then print("result handler is here ",rData[key]) return else NetManager:receiveMsg(msgid,rData) end end -- readData function scnet.readData( ba,msg_type,data) local key = msg_type.key if key then data[key] = data[key] or {} local _type = msg_type["fmt"] if type(_type) == "string" then if _type == "string" then data[key] = ba:readStringUShort() elseif _type == "number" then data[key] = ba:readLuaNumber() elseif _type == "int" then data[key] = ba:readInt() elseif _type == "short" then data[key] = ba:readShort() end if key == "result" then -- 当结果不为零的时候,说明有错误 if data[key] ~= 0 then print("result handler is here ",data[key]) return end end else local _len = ba:readShort() -- 读取数组长度 for i=1,_len do local tmp = {} for j=1,#_type do scnet.readData(ba,_type[j],tmp) end table.insert(data[key],tmp) end end else print("找不到对应的 key scnet.readData",msg_type.key,msg_type,data) end end -- 数据解密 function scnet.decodeByte( byte ) local tmp = bit.band(bit.bnot(bit.band(byte,255)),255) tmp = bit.band((tmp + 256 - 80),255) return tmp end
-- 发送 MsgFmt["1001"] = { { key = "list", fmt = { { key = "id",fmt = "int" }, { key = "name",fmt = "string" }, { key = "level",fmt = "int" }, { key = "sex",fmt = "int" } } }, { key = "userid",fmt = "int" } } -- 返回 MsgFmt["5001"] = { { key = "result",fmt = "int" }, { key = "list", fmt = { { key = "id",fmt = "int" }, { key = "name",fmt = "string" }, { key = "level",fmt = "int" }, { key = "sex",fmt = "int" } } } }
-- 网络通讯管理类 NetManager = class("NetManager") local port = 8080 local host = "192.168.1.28" -- 初始化 function NetManager:init( ) self._listenerList = {} scnet.init() scnet.connect(host,port) end -- 注册消息 -- 注册之后 接受到服务器消息之后进行广播,谁注册,谁相应 function NetManager:registerMsg( msgid,callBack ) self._listenerList[msgid] = self._listenerList[msgid] or {} local isExist = self:findCallBack(msgid,callBack) if not isExist then table.insert(self._listenerList[msgid],callBack) end end -- 移除注册消息 function NetManager:removeRegister( msgid,callBack ) if self._listenerList[msgid] then for k,v in pairs(self._listenerList) do if v == callBack then self._listenerList[msgid][k] = nil end end end end -- 移除所有注册消息 function NetManager:removeAllMsg( ) self._listenerList = nil self._listenerList = {} end -- 发送消息 -- 整理数据发送给服务器 function NetManager:sendMsg( msgid,data ) scnet.send(msgid,data) end -- 接受消息 -- 派发事件 function NetManager:receiveMsg( msgid,data ) if self._listenerList[msgid] then for k,v in pairs(self._listenerList[msgid]) do v(data) end end end function NetManager:findCallBack( msgid,callBack ) for k,v in pairs(self._listenerList[msgid]) do if v == callBack then return true end end return false end
function MainScene:onEnter() -- 添加消息事件监听 NetManager:registerMsg(MsgType.SC_LOGIN ,handler(self,self.receiveHandler)) -- test 发送事件 -- 构造根据消息格式构造数据 local data = {} data.list = {} table.insert(data.list,{id = 1001,name = "小房",level = 1,sex = 1}) table.insert(data.list,{id = 1002,name = "1111",level = 11,sex = 2}) table.insert(data.list,{id = 1003,name = "2222",level = 21,sex = 3}) table.insert(data.list,{id = 1004,name = "3333",level = 31,sex = 2}) data.userid = 10001 NetManager:sendMsg(MsgType.CS_LOGIN,data) end function MainScene:onExit() -- 移除消息事件监听 NetManager:removeRegister(MsgType.SC_LOGIN ,handler(self,self.receiveHandler)) end