local MBSocket = EapClass("MBSocket") local scheduler = import(".scheduler") local proto = import(".proto") local SOCKET_NUM_COUNT = 1 function MBSocket:ctor() self._mbSocket = nil self._listener = {} self._adapter = {} self._sendData = {} self._address = nil self._connected = false self._schedulerID = -1 self._closeBack = nil --断线回调 self:initData() end function MBSocket:initData() end -- 心跳时间 local KEEP_ALIVE_TIMEOUT = 30 function MBSocket:isConnected() return self._connected end -- 地址,端口,链接成功回调,链接失败回调,收到消息回调 function MBSocket:connect(address, closeBack, connectBack) if (self._connected) then if (connectBack) then connectBack(true) end return true end if (not address) then return false end self._mbSocket = cc.WebSocket:create(address) if not self._mbSocket then print("创建连接失败" .. address) return false end if (self._mbSocket:getReadyState()>=2) then if (self._mbSocket) then self._mbSocket.close() self._mbSocket = nil end if (connectBack) then connectBack(false) return false end return false end self._address = address self._closeBack = closeBack self._connectBack = connectBack local function OnOpen(strData) print("MBSocket OnOpen") if (self._connectBack) then local callback = self._connectBack self._connectBack = nil callback(true); end -- 发送极限数据 if (#self._sendData>0) then self._mbSocket:sendString(self._sendData[1]) table.remove(self._sendData, 1) end end local function OnMessage(strData) if type(strData) == "table" then strData = string.char(unpack(strData)) end local opcode, data = self:parsePacket(strData) -- local data = G_EapSdkJson.decode(strData) self:onReceivedData(opcode, data) end --区分是否当前创建的socket local curSocketNum = SOCKET_NUM_COUNT + 1 SOCKET_NUM_COUNT = SOCKET_NUM_COUNT + 1 self._mbSocket.socketNum = curSocketNum local function OnClose(strData) print("MBSocket OnClose", self._mbSocket.socketNum, curSocketNum) self._connected = false; if (self._mbSocket and self._mbSocket.socketNum == curSocketNum)then self:onclose() end end local function OnError(strData) print("MBSocket OnClose", self._mbSocket.socketNum, curSocketNum) if (self._mbSocket and self._mbSocket.socketNum == curSocketNum)then self:onclose() end end -- 注册回调以上的函数 if nil ~= self._mbSocket then self._mbSocket:registerScriptHandler(OnOpen,cc.WEBSOCKET_OPEN) self._mbSocket:registerScriptHandler(OnMessage,cc.WEBSOCKET_MESSAGE) self._mbSocket:registerScriptHandler(OnClose,cc.WEBSOCKET_CLOSE) self._mbSocket:registerScriptHandler(OnError,cc.WEBSOCKET_ERROR) end self._connected = true self._schedulerID = scheduler.scheduleGlobal(handler(self, self.peakPacket), 0.1) return true end --重新连接 function MBSocket:reConnect() return self:connect(self._address, self._onClose) end -- 关闭连接 function MBSocket:close() self:onclose() end function MBSocket:onclose() self._connected = false self._sendData = {} if (self._mbSocket) then scheduler.unscheduleGlobal(self._schedulerID) self._mbSocket:unregisterScriptHandler(cc.WEBSOCKET_OPEN) self._mbSocket:unregisterScriptHandler(cc.WEBSOCKET_MESSAGE) self._mbSocket:unregisterScriptHandler(cc.WEBSOCKET_CLOSE) self._mbSocket:unregisterScriptHandler(cc.WEBSOCKET_ERROR) self._mbSocket:close(); self._mbSocket = nil; end if (self._connectBack) then local callback = self._connectBack self._connectBack = nil; callback(false); elseif (self._closeBack) then local callback = self._closeBack self._closeBack = nil; callback(false); end end -- 这里是提供给LUA逻辑层的网络协议发送接口 function MBSocket:sendPacket(opcode, data) if (self._mbSocket) then if (self._mbSocket:getReadyState() == cc.WEBSOCKET_STATE_CONNECTING) then local buffer = self:serializePacket(opcode, data) self._sendData[#self._sendData+1] = buffer return end else print("连接断开,不重新连接服务器") if (self._serType == SER_TYPE_LOGIN) then local buffer = self:serializePacket(opcode, data) self._sendData[#self._sendData+1] = buffer self:reConnect() end return end if (self._mbSocket) then local buffer = self:serializePacket(opcode, data) self._sendData[#self._sendData+1] = buffer --self._mbSocket:sendString(data) end end function MBSocket:peakPacket() if (self._mbSocket and #self._sendData>0) then print("MBSocket:peakPacket = ", type(self._sendData[1]), string.len(self._sendData[1])) self._mbSocket:sendString(self._sendData[1]) table.remove(self._sendData, 1) end end function MBSocket:onReceivedData(opcode, data) assert(false, "MBSocket:onReceivedData 此方法需要被继承") end -- | compress | 1 | 0:未压缩, 1:压缩,只针对data字段压缩 | -- | format | 7 | 0:自定义, 1:protobuf, 2:json,3:xml | -- | 扩展字段 | 8 | 自定义数据格式,原样返回, app用来定义消息id用的,自增,app可以用来区分是哪条消息的返回数据 -- | opcode | 16 | 网络协议的类型标识,根据该标识进行反序列化 | -- | len | 16 | 网络包的长度,其值为除len字段外的其它所有长度 | -- len可以没有,如果compress==0;没有len;compress==1;才有len字段 function MBSocket:serializePacket(opcode, data) if data and opcode and G_EapProtos[opcode] then print("发送数据:", opcode) EapDump(data) local len = 0 local buffer = proto.serialize(data, G_EapProtos[opcode]) len = len + string.len(buffer) local opcodeStr = proto.int16ToBufStr(opcode) local op1 = 1 local op1Str = string.char(op1) local op2 = 0 local op2Str = string.char(op2) len = len + 4 if op1 == 1 then buffer = op1Str..op2Str..opcodeStr..buffer elseif op1 == 129 then local op3 = len local op3Str = string.char(op3) buffer = op1Str..op2Str..opcodeStr..op3Str..buffer end return buffer end end function MBSocket:parsePacket(buffer) local tbl = nil local opcode = nil local op1 = string.byte(buffer, 1, 1) local compress = bit.rshift(op1, 7) local type = bit.band(op1, 0x7f) local dataIndex = 5 if compress == 1 then dataIndex = 7 end local op2, op3 = string.byte(buffer, 3, 4) opcode = proto.buffToInt16(op2, op3) print("MBSocket:parsePacket Opcode == ", opcode, compress, type, string.len(buffer)) if G_EapProtos[opcode] then local leftBuff = string.sub(buffer, dataIndex) tbl = proto.parse(leftBuff, G_EapProtos[opcode]) EapDump(tbl) else print("MBSocket:parsePacket proto not exist!!!") end return opcode, tbl end return MBSocket