Quick-cocos2d-x v3.3 SocketTCP链接

Quick-Cocos2d-x v3.3里面提供了两种长连接WebSockets、SocketTCP,这里说一下SocketTCP的用法。


1
2
3
local net = require( "framework.cc.net.init" )
local ByteArray = require( "framework.cc.utils.ByteArray" )
require( "framework.cc.utils.bit" )


-- 网络初始化,添加侦听函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

 

--发送数据给服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function scnet.send( msgid,data )
  --  encodeData 此方法是根据需要发送的数据安装与服务器定义好的消息格式去write
  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
  -- 最后再组成一个新的ByteArray
  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来确定数据格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function scnet.encodeData( msgid,data )
  if  msgid then
  local ba = ByteArray. new (ByteArray.ENDIAN_BIG)
  local fmt = InfoUtil:getMsgFmt(msgid)  -- 此处为读取消息格式 看下面的MessageType里面会有定义
  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

  

-- write 数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function scnet.writeData( ba,msg_type,data )
   
  local key = msg_type.key
  print( "scnet.writeData" , "key" ,key)
  if  key and data[key] then
  local _type = msg_type[ "fmt" ]
  if  type(_type) ==  "string"  then
  if  _type ==  "string"  then
  ba:writeStringUShort(data[key])
  elseif _type ==  "number"  then
  ba:writeLuaNumber(data[key])
  elseif _type ==  "int"  then
  ba:writeInt(data[key])
  elseif _type ==  "short"  then
  ba:writeShort(data[key])
  end
  else
  ba:writeShort(#data[key])
  for  k,v in pairs(data[key])  do
  for  i=1,#_type  do
  scnet.writeData(ba,_type<i>,v)
  end
  end
  end
  else
  print( "找不到对应的 key" ,msg_type.key,msg_type,data)
  end
end


-- 读取数据

-- 接收消息

1
2
3
4
5
6
7
8
9
10
11
12
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

 

-- 消息数据解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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

 

-- 根据格式解析数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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

 

-- 数据解密

1
2
3
4
5
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


消息格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
-- 发送
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

管理网络的发送与接收

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
-- 初始化
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: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

  

test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- 监听事件
function MainScene:onEnter()
  NetManager:registerMsg(MsgType.SC_LOGIN ,handler(self,self.receiveHandler))
end
  
-- 移除坚挺
function MainScene:onExit()
     NetManager:removeRegister(MsgType.SC_LOGIN ,handler(self,self.receiveHandler))
end
 
-- 发送数据,根据MsgFmt构造数据
  local data = {}
   data.list = {}
   table.insert(data.list,{id = 1001,name =  "小房" ,level = 1,sex = 1})
   table.insert(data.list,{id = 1002,name =  "小田" ,level = 11,sex = 2})
   table.insert(data.list,{id = 1003,name =  "2222" ,level = 21,sex = 1})
   table.insert(data.list,{id = 1004,name =  "3333" ,level = 31,sex = 2})
   data.userid = 10001
   NetManager:sendMsg(MsgType.CS_LOGIN,data)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值