| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529 |
- import DataModelBase from '../framework/DataModelBase';
- import Event from './Event';
- import Common from '../common/Common';
- import CCipher from '../common/CCipher';
- import Packet from '../net/Packet';
- import ConstMsgId from '../net/ConstMsgId';
- import MsgTransfer from '../net/MsgTransfer';
- import Define from '../common/Define';
- //var protobuf = require("protobufjs");
- //var PBTransfer = require("PBTransfer");
- //var ByteBuffer = protobuf.ByteBuffer;
- export default class Connect extends DataModelBase
- {
- constructor(url,isShortConnect)
- {
- super('Connect');
- this._url = url;
- Common.Print('Connect url:' + url);
- this._isShortConnect = isShortConnect;
- this._state = Common.SocketState.Closed;
- this._webSocket = null;
- this._protoLoaded = false;
- this._protoMsgClass = {};
- this._messageIndex = 0;
- this._bNeedClose = false; // 客户端需要被主动关闭
- this._reConnectInterval = 3000;
- this._bReconnect = false;
- this._closeTimeOut = null;
- this._errorTimeOut = null;
- this._timeOut = null;
- this._sendDataBuf = new Array();
- this._heatInterval = 15000;//15 second
- this._pingTimes = 0;
- this._socketType = Define.SOCKET_TYPE.PLAZA
- }
- // var protoFiles = [
- // ["resources/proto/authmsg.proto", "./authmsg.proto"],
-
- // ["resources/proto/commsg.proto", "./commsg.proto"],
-
- // ["resources/proto/gamemsg.proto", "./gamemsg.proto"]
-
- // ];
- //加载proto文件,在游戏初始时进行,推荐在资源加载时调用
- //需要等待proto全部加载完成之后,才能使用socket
- loadProto (protoFiles,callback)
- {
- let con = this
- con._protoMsgClass = {};
-
- cc.loader.loadResDir("proto", function(err, array)
- {
- for (var i=0, dep, data; i<protoFiles.length; i++)
- {
- dep = protoFiles[i];
-
- var realUrl = cc.url.raw(dep[0]);
- var proto_msg = array[i].text;
- var msg_builder = protobuf.loadProto(proto_msg, dep[1]);
- con.analiseNameSpace(msg_builder, con._protoMsgClass);
- }
- con._protoLoaded = true;
- Common.Print('_protoLoaded '+ con._protoLoaded);
- PBTransfer.setProtoClassHolder(con._protoMsgClass);
- if(callback)
- {
- callback.call();
- }
- });
- }
- //解析一个proto ns,将其中所有的builder都缓存起来
- analiseNameSpace (builder, classHolder)
- {
- if(!builder)
- return;
- if(!classHolder)
- return;
- if(!builder.ns)
- return;
-
- var children = builder.ns.children;
- if(!children)
- return;
- var child = children[0];
- if(!child)
- return;
- var packageName = "";
- //has package;
- while(child.className == "Namespace")
- {
- if(packageName.length == 0)
- packageName += child.name;
- else
- packageName += "." + child.name;
- children = child.children;
- if(!children)
- return;
- child = children[0];
- if(!child)
- return;
- }
- for(var child of children)
- {
- var name = child.name;
- if(!name)
- continue;
- if(packageName.length == 0)
- classHolder[name] = builder.build(name);
- else
- classHolder[name] = builder.build(packageName + "." + name);
- }
- }
- getConnectState()
- {
- if(this._webSocket == null)
- {
- return this._state;
- }
- if(this._webSocket.readyState == WebSocket.CONNECTING)
- {
- this._state = Common.SocketState.Connecting;
- }
- else if(this._webSocket.readyState == WebSocket.OPEN)
- {
- this._state = Common.SocketState.OK;
- }
- else if(this._webSocket.readyState == WebSocket.CLOSING)
- {
- this._state = Common.SocketState.Closing;
- }
- else if(this._webSocket.readyState == WebSocket.CLOSED)
- {
- this._state = Common.SocketState.Closed;
- }
- else
- {
- //noting to do
- }
- //Common.Print("this._state:" + this._state);
- return this._state;
- }
- open( bReconnect)
- {
- Common.Print(" connect open" + this._url)
- this._bNeedClose = false
- if(this._timeOut != null)
- {
- clearTimeout(this._timeOut);
- this._timeOut = null;
- }
- if(!this._url || typeof(this._url) !== "string" || this._url.length == 0)
- return -1;
- if(this._state == Common.SocketState.Connecting)//正在连接中......
- {
- // return this._state;
- Common.Print(" connect open Common.SocketState.Connecting")
- return 0
- }
- if(bReconnect == true)
- {
- this._bReconnect = true;
- this.emit(Event.SOCKET_MSG.RECONNECT_START);
- }
- this.close()
- this._bNeedClose = false; // 客户端主动关闭
- this._webSocket = null;
- console.log('open:cc.sys.os: ' + cc.sys.os + ' CC_JSB:' + CC_JSB + ' cc.sys.isMobile:' + cc.sys.isMobile)
- if(CC_JSB && cc.sys.OS_ANDROID === cc.sys.os)
- {
- var pemUrl = cc.url.raw('resources/key/server.pem')
- if(cc.loader.md5Pipe)
- {
- pemUrl = cc.loader.md5Pipe.transformURL('resources/key/server.pem')
- }
- //this._webSocket = new WebSocket(this._url,'',pemUrl);
- this._webSocket = new WebSocket(this._url);
- }
- else
- {
- this._webSocket = new WebSocket(this._url);
- }
-
- this._webSocket.binaryType = "arraybuffer";
- this._webSocket.onopen = this._onOpen.bind(this);
- this._webSocket.onmessage = this._onMessage.bind(this);
- this._webSocket.onerror = this._onError.bind(this);
- this._webSocket.onclose = this._onClose.bind(this);
- this._state = Common.SocketState.Connecting;
- return 0;
- }
- //主动关闭连接
- close()
- {
- if(!this._webSocket || !(this._webSocket instanceof WebSocket))
- return -1;
- if(this.getConnectState() == Common.SocketState.Closed)
- return this._state;
- this._state = Common.SocketState.Closed;
- this._webSocket.close();
- this._messageIndex = 0;
- this._bNeedClose = true; // 客户端主动关闭
- this._bReconnect = false;
- }
- sendSocketData(wMain, wSub, pData,wDataSize)
- {
- }
- sendMsg(msg)
- {
-
- CCipher.encryptBuffer(msg,msg.byteLength)
- this._sendData(msg)
- }
-
- getUrl()
- {
- return this._url;
- }
- /////////////////////////////////////////私有方法和属性/////////////////////////////////////
- //连接监听
- _onOpen (evt)
- {
-
- Common.Print('Connect _onOpen start')
- this._bNeedClose = false; // 客户端主动关闭
- this._state = Common.SocketState.OK;
- this._pingTimes = 0;
- if(this._bReconnect == true)
- {
- this.emit(Event.SOCKET_MSG.RECONNECT_OK);
- this._bReconnect = false;
- }
-
- this.emit(Event.SOCKET_MSG.OPEN)
-
- if(this._closeTimeOut != null)
- {
- clearTimeout(this._closeTimeOut);
- this._closeTimeOut = null;
- }
- if(this._errorTimeOut != null)
- {
- clearTimeout(this._errorTimeOut);
- this._errorTimeOut = null;
- }
- if(this._timeOut != null)
- {
- clearTimeout(this._timeOut);
- this._timeOut = null;
- }
- this.checkHeartBeat();
- Common.Print('Connect _onOpen end')
- }
- sendBufData()
- {
- for (var i = 0; i < this._sendDataBuf.length ; i++)
- {
- this.sendData(this._sendDataBuf[i].msgid,this._sendDataBuf[i].msgdata);
- }
- this._sendDataBuf = [];
- }
- //返回监听
- _onMessage (evt)
- {
- //解析返回的消息
- // 粘包、拆包
- // if (evt.data instanceof Blob)
- // {
- // console.log("Blob")
- // }
- if(typeof(evt.data)=="string")
- {
- console.log("string")
- }
- Common.Print('Connect _onMessage')
- console.log(evt.data)
- Common.Print(typeof(evt.data))
-
- var dataview = new DataView(evt.data)
- var dataviewLength = evt.data.byteLength
- if(dataviewLength < Packet.TCPInfoSize) //
- {
- console.log("dataviewLength< Packet.TCPInfoSize(4)")
- return
- }
- CCipher.decryptBuffer(evt.data,evt.data.byteLength)
- var readPos = 0
- var cbDataKind = dataview.getUint8(readPos,Common.littleEndian)
- readPos +=1
- var cbCheckCode = dataview.getUint8(readPos,Common.littleEndian)
- readPos +=1
- var wPacketSize = dataview.getUint16(readPos,Common.littleEndian)
- readPos +=2
- var wMainCmdID = dataview.getUint16(readPos,Common.littleEndian)
- readPos +=2
- var wSubCmdID = dataview.getUint16(readPos,Common.littleEndian)
- readPos +=2
- if(wMainCmdID != ConstMsgId.MDM_KN_COMMAND && wSubCmdID != ConstMsgId.SUB_KN_DETECT_SOCKET )
- {
-
- Common.Print("_onMessage wMainCmdID:" + wMainCmdID + " wSubCmdID:" + wSubCmdID + " wPacketSize:" + wPacketSize)
- }
-
- if(wMainCmdID == ConstMsgId.MDM_KN_COMMAND && wSubCmdID == ConstMsgId.SUB_KN_DETECT_SOCKET)
- {
- this.pingTimes = this.pingTimes - 1
- }
- if(wMainCmdID > 0 || wSubCmdID != Packet.SUB_KN_DETECT_SOCKET)
- {
- var pack = null
- if(dataviewLength > Packet.TCPInfoSize)
- {
- var packBuf = evt.data.slice(Packet.TCPHeadSize,dataviewLength)
- }
- this.emit(Event.SOCKET_MSG.DATA, wMainCmdID,wSubCmdID,packBuf)
- }
-
- }
- //错误监听
- _onError(evt) {
- //GH.log("GameSocket _onError", evt);
- console.log(Common.GetDateString() + 'GameSocket _onError'+ JSON.stringify(evt))
- let self = this;
- this._state = Common.SocketState.Error;
- if(this._timeOut!=null)
- {
- clearTimeout(this._timeOut);
- this._timeOut = null;
- }
- if(this._bNeedClose != true)
- {
- this._errorTimeOut = setTimeout(function() {
- self.open(true);
- }, self._reConnectInterval);
- }
-
- this.emit(Event.SOCKET_MSG.ERROR);
- }
- //关闭监听
- _onClose(evt)
- {
- console.log(Common.GetDateString() + 'GameSocket _onClose'+ JSON.stringify(evt))
- var state = this.getConnectState()
- console.log(Common.GetDateString() + 'GameSocket _onClose state :'+ state)
- if( Common.SocketState.OK == state )
- {
- return
- }
- this._state = Common.SocketState.Closed;
- var bClientClosed = this._bClientClosed;
- let self = this;
- if(this._timeOut!=null)
- {
- clearTimeout(this._timeOut);
- this._timeOut = null;
- }
- if(this._bNeedClose != true)
- {
- this._closeTimeOut = setTimeout(function() {
-
- self.open(true);
-
- }, self._reConnectInterval);
- }
-
- this.emit(Event.SOCKET_MSG.CLOSE,bClientClosed);
- }
-
- _sendData(dataBuf)
- {
- if(!dataBuf || !(dataBuf instanceof ArrayBuffer))
- return -1;
- if (!this._webSocket)
- return -1;
- if(this.getConnectState() != Common.SocketState.OK)
- {
- return this._state;
- }
- if (this._webSocket.readyState === WebSocket.OPEN) {
-
- console.log('_sendData')
- this._webSocket.send(dataBuf);
-
- return 0;
- } else {
- this._state = this.getConnectState();
- //this._webSocket.close();
- return this._state;
-
- }
-
-
- }
-
- checkHeartBeat()
- {
- var self = this;
- // if(this._bClientClosed = true)
- // {
- // return
- // }
-
- self._timeOut = setTimeout(function () {
- if(self._bNeedClose != true)
- {
- if (self.pingTimes >= 3) //6次没有收到ping消息,认为断了线
- {
- Common.Print('pingTimes >= 3');
- self.pingTimes = 0;
- self.open(true);//认为已经断开连接//然后重连
- return;
- }
- //记录心跳次数
- self.pingTimes++;
- self.sendPing();
- }
- self.checkHeartBeat();
- }, this._heatInterval);
- }
- sendPing()
- {
-
- console.log(Common.GetDateString() + 'sendPing');
- var msg = MsgTransfer.encodemsg(ConstMsgId.MDM_KN_COMMAND ,ConstMsgId.SUB_KN_DETECT_SOCKET,4 + 4 )
- var sre = "hert"
- console.log('msg is: ',sre);
- this.sendMsg(sre);
- }
- }
|