You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

236 lines
6.7 KiB

  1. local MBSocket = EapClass("MBSocket")
  2. local scheduler = import(".scheduler")
  3. local proto = import(".proto")
  4. local SOCKET_NUM_COUNT = 1
  5. function MBSocket:ctor()
  6. self._mbSocket = nil
  7. self._listener = {}
  8. self._adapter = {}
  9. self._sendData = {}
  10. self._address = nil
  11. self._connected = false
  12. self._schedulerID = -1
  13. self._closeBack = nil --断线回调
  14. self:initData()
  15. end
  16. function MBSocket:initData()
  17. end
  18. -- 心跳时间
  19. local KEEP_ALIVE_TIMEOUT = 30
  20. function MBSocket:isConnected()
  21. return self._connected
  22. end
  23. -- 地址,端口,链接成功回调,链接失败回调,收到消息回调
  24. function MBSocket:connect(address, closeBack, connectBack)
  25. if (self._connected) then
  26. if (connectBack) then
  27. connectBack(true)
  28. end
  29. return true
  30. end
  31. if (not address) then
  32. return false
  33. end
  34. self._mbSocket = cc.WebSocket:create(address)
  35. if not self._mbSocket then
  36. print("创建连接失败" .. address)
  37. return false
  38. end
  39. if (self._mbSocket:getReadyState()>=2) then
  40. if (self._mbSocket) then
  41. self._mbSocket.close()
  42. self._mbSocket = nil
  43. end
  44. if (connectBack) then
  45. connectBack(false)
  46. return false
  47. end
  48. return false
  49. end
  50. self._address = address
  51. self._closeBack = closeBack
  52. self._connectBack = connectBack
  53. local function OnOpen(strData)
  54. print("MBSocket OnOpen")
  55. if (self._connectBack) then
  56. local callback = self._connectBack
  57. self._connectBack = nil
  58. callback(true);
  59. end
  60. -- 发送极限数据
  61. if (#self._sendData>0) then
  62. self._mbSocket:sendString(self._sendData[1])
  63. table.remove(self._sendData, 1)
  64. end
  65. end
  66. local function OnMessage(strData)
  67. if type(strData) == "table" then
  68. strData = string.char(unpack(strData))
  69. end
  70. local opcode, data = self:parsePacket(strData)
  71. -- local data = G_EapSdkJson.decode(strData)
  72. self:onReceivedData(opcode, data)
  73. end
  74. --区分是否当前创建的socket
  75. local curSocketNum = SOCKET_NUM_COUNT + 1
  76. SOCKET_NUM_COUNT = SOCKET_NUM_COUNT + 1
  77. self._mbSocket.socketNum = curSocketNum
  78. local function OnClose(strData)
  79. print("MBSocket OnClose", self._mbSocket.socketNum, curSocketNum)
  80. self._connected = false;
  81. if (self._mbSocket and self._mbSocket.socketNum == curSocketNum)then
  82. self:onclose()
  83. end
  84. end
  85. local function OnError(strData)
  86. print("MBSocket OnClose", self._mbSocket.socketNum, curSocketNum)
  87. if (self._mbSocket and self._mbSocket.socketNum == curSocketNum)then
  88. self:onclose()
  89. end
  90. end
  91. -- 注册回调以上的函数
  92. if nil ~= self._mbSocket then
  93. self._mbSocket:registerScriptHandler(OnOpen,cc.WEBSOCKET_OPEN)
  94. self._mbSocket:registerScriptHandler(OnMessage,cc.WEBSOCKET_MESSAGE)
  95. self._mbSocket:registerScriptHandler(OnClose,cc.WEBSOCKET_CLOSE)
  96. self._mbSocket:registerScriptHandler(OnError,cc.WEBSOCKET_ERROR)
  97. end
  98. self._connected = true
  99. self._schedulerID = scheduler.scheduleGlobal(handler(self, self.peakPacket), 0.1)
  100. return true
  101. end
  102. --重新连接
  103. function MBSocket:reConnect()
  104. return self:connect(self._address, self._onClose)
  105. end
  106. -- 关闭连接
  107. function MBSocket:close()
  108. self:onclose()
  109. end
  110. function MBSocket:onclose()
  111. self._connected = false
  112. self._sendData = {}
  113. if (self._mbSocket) then
  114. scheduler.unscheduleGlobal(self._schedulerID)
  115. self._mbSocket:unregisterScriptHandler(cc.WEBSOCKET_OPEN)
  116. self._mbSocket:unregisterScriptHandler(cc.WEBSOCKET_MESSAGE)
  117. self._mbSocket:unregisterScriptHandler(cc.WEBSOCKET_CLOSE)
  118. self._mbSocket:unregisterScriptHandler(cc.WEBSOCKET_ERROR)
  119. self._mbSocket:close();
  120. self._mbSocket = nil;
  121. end
  122. if (self._connectBack) then
  123. local callback = self._connectBack
  124. self._connectBack = nil;
  125. callback(false);
  126. elseif (self._closeBack) then
  127. local callback = self._closeBack
  128. self._closeBack = nil;
  129. callback(false);
  130. end
  131. end
  132. -- 这里是提供给LUA逻辑层的网络协议发送接口
  133. function MBSocket:sendPacket(opcode, data)
  134. if (self._mbSocket) then
  135. if (self._mbSocket:getReadyState() == cc.WEBSOCKET_STATE_CONNECTING) then
  136. local buffer = self:serializePacket(opcode, data)
  137. self._sendData[#self._sendData+1] = buffer
  138. return
  139. end
  140. else
  141. print("连接断开,不重新连接服务器")
  142. if (self._serType == SER_TYPE_LOGIN) then
  143. local buffer = self:serializePacket(opcode, data)
  144. self._sendData[#self._sendData+1] = buffer
  145. self:reConnect()
  146. end
  147. return
  148. end
  149. if (self._mbSocket) then
  150. local buffer = self:serializePacket(opcode, data)
  151. self._sendData[#self._sendData+1] = buffer
  152. --self._mbSocket:sendString(data)
  153. end
  154. end
  155. function MBSocket:peakPacket()
  156. if (self._mbSocket and #self._sendData>0) then
  157. print("MBSocket:peakPacket = ", type(self._sendData[1]), string.len(self._sendData[1]))
  158. self._mbSocket:sendString(self._sendData[1])
  159. table.remove(self._sendData, 1)
  160. end
  161. end
  162. function MBSocket:onReceivedData(opcode, data)
  163. assert(false, "MBSocket:onReceivedData 此方法需要被继承")
  164. end
  165. -- | compress | 1 | 0:未压缩, 1:压缩,只针对data字段压缩 |
  166. -- | format | 7 | 0:自定义, 1:protobuf, 2:json,3:xml |
  167. -- | 扩展字段 | 8 | 自定义数据格式,原样返回, app用来定义消息id用的,自增,app可以用来区分是哪条消息的返回数据
  168. -- | opcode | 16 | 网络协议的类型标识,根据该标识进行反序列化 |
  169. -- | len | 16 | 网络包的长度,其值为除len字段外的其它所有长度 |
  170. -- len可以没有,如果compress==0;没有len;compress==1;才有len字段
  171. function MBSocket:serializePacket(opcode, data)
  172. if data and opcode and G_EapProtos[opcode] then
  173. print("发送数据:", opcode)
  174. EapDump(data)
  175. local len = 0
  176. local buffer = proto.serialize(data, G_EapProtos[opcode])
  177. len = len + string.len(buffer)
  178. local opcodeStr = proto.int16ToBufStr(opcode)
  179. local op1 = 1
  180. local op1Str = string.char(op1)
  181. local op2 = 0
  182. local op2Str = string.char(op2)
  183. len = len + 4
  184. if op1 == 1 then
  185. buffer = op1Str..op2Str..opcodeStr..buffer
  186. elseif op1 == 129 then
  187. local op3 = len
  188. local op3Str = string.char(op3)
  189. buffer = op1Str..op2Str..opcodeStr..op3Str..buffer
  190. end
  191. return buffer
  192. end
  193. end
  194. function MBSocket:parsePacket(buffer)
  195. local tbl = nil
  196. local opcode = nil
  197. local op1 = string.byte(buffer, 1, 1)
  198. local compress = bit.rshift(op1, 7)
  199. local type = bit.band(op1, 0x7f)
  200. local dataIndex = 5
  201. if compress == 1 then
  202. dataIndex = 7
  203. end
  204. local op2, op3 = string.byte(buffer, 3, 4)
  205. opcode = proto.buffToInt16(op2, op3)
  206. print("MBSocket:parsePacket Opcode == ", opcode, compress, type, string.len(buffer))
  207. if G_EapProtos[opcode] then
  208. local leftBuff = string.sub(buffer, dataIndex)
  209. tbl = proto.parse(leftBuff, G_EapProtos[opcode])
  210. EapDump(tbl)
  211. else
  212. print("MBSocket:parsePacket proto not exist!!!")
  213. end
  214. return opcode, tbl
  215. end
  216. return MBSocket