import { FrameworkConf } from "../../framework/config/FrameworkConf"; import { Framework } from "../../framework/Framework"; import { GameEvent } from "../data/GameEvent"; import { StringUtil } from "../../framework/util/StringUtil"; import { ViewID } from "../../framework/config/LayerConf"; export let NetMgr: NetManager = null; export class NetManager { private _socket: WebSocket = null; private _web_url = ""; //服务器地址 private _callback: Function = null; private _hear_time = 5; //心跳时间 private _hear_time_out = 2; //心跳超次数() private _hear_time_cur = 0; //心跳超时次数 private _hear_uuid = 0; //心跳定时器 private _is_connect = false; //网络是否连接 private _bReconnect = false; //是否重连 private _bHandShake = false; //是否握手 private _bProClose = false; //是否主动断开 private _uid = 0; private _seq = 0; //心跳超时 自动重连,超过5次则不再重连 private _auto_reconnect_time = 0; private _auto_reconnect_time_out = 5; private _socketId = 0; static get instance() { if (NetMgr == null) { NetMgr = new NetManager(); } return NetMgr; } //网络是否连接 get is_connect() { return this._is_connect; } get is_handShake() { return this._bHandShake; } get bReconnect() { return this._bReconnect; } get bProClose() { return this._bProClose; } connect(url: string, callback: Function) { //this.close(false); let socketId = ++this._socketId this._clearHeart(); this._web_url = url; this._callback = callback; this._socket = new WebSocket(this._web_url, 'default-protocol'); this._socket.binaryType = "arraybuffer"; this._socket.onopen = (event: any) => { if(socketId != this._socketId){ return } callback && callback(0); callback = null; this._is_connect = true; this._bProClose = false this._auto_reconnect_time = 0 this._hear_time_cur = 0 }; this._socket.onerror = (event: any) => { if(socketId != this._socketId){ return } console.log("onerror:", event," socketId:",socketId); callback && callback(1); callback = null; this._is_connect = false; this._bHandShake = false this._clearHeart(); // this._socket = null // this._autoReconnect(3) Framework.event.fireEvent(FrameworkConf.Event.NET_ERROR, event); }; this._socket.onclose = (event: any) => { if(socketId != this._socketId){ return } console.log("onclose1:", event," socketId:",socketId); this._is_connect = false; this._bHandShake = false this._bReconnect = false this._clearHeart(); this._socket = null Framework.layer.open(ViewID.MaskUI,()=>{}); if(!this._bProClose){ this._autoReconnect(3) } else Framework.event.fireEvent(FrameworkConf.Event.NET_CLOSE, event); }; this._socket.onmessage = (event: any) => { let Json = JSON.parse(event.data) // console.log(Json); if (Json.mod == 'user' && Json.act == 'handshake') { this._startHeart(); if (Json.code == 0) { Framework.layer.close(ViewID.MaskUI); this._bHandShake = true // if(Framework.layer.getUIView(ViewID.BombUI)){ //window.parent.postMessage(FrameworkConf.Event.NET_RECONNECT, "*"); this._uid = Json.data._id Framework.event.fireEvent(FrameworkConf.Event.NET_RECONNECT, {}); this._bReconnect = false //} // if(!Framework.layer.getUIView(ViewID.BombUI)){ // var args = { 'uid': Json.data._id, 'cash': Json.data.cash, 'state': 1 }; // Framework.layer.open(ViewID.BombUI, null, args); // } }else { this.close(false) Framework.event.fireEvent(FrameworkConf.Event.NET_HANDSHAKE_ERROR, Json.code); // 弹窗提示登陆失败 Framework.tips.setTips(Json.desc); } }else if (Json.mod == 'user' && Json.act == 'heart_beat') { this._hear_time_cur = 0; //console.error(Json) } else { if (Json.seq == this._seq) { // 解开遮罩 } // console.log("onmessage:",event.data); Framework.event.fireEvent(FrameworkConf.Event.NET_MSG, Json); } }; } /** * 关闭socket * @param bReconnect 是否重连 */ close(bReconnect) { console.log("close test"); this._socket && this._socket.close(); this._socket = null; this._is_connect = false; this._bHandShake = false this._bProClose = true; this._clearHeart(); // window.parent.postMessage(FrameworkConf.Event.NET_CLOSE, "*"); if(bReconnect){ Framework.layer.open(ViewID.MaskUI); this._autoReconnect() } else{ Framework.layer.open(ViewID.MaskUI,()=>{},{closeTime:0}); console.error("断开连接") } } send(msg: any) { //msg.uid = UserData['_id']; let msgStr = JSON.stringify(msg) // console.log(msgStr); // console.log(this._socket); if (this._socket) { // // let strBuf = this.protoEncode(cmd, msg); // // let buf = this.packet(strBuf); this._socket.send(msgStr) } } // uint8Array转typedArray typedArray(uint8Array) { var hex = Array.prototype.map .call(uint8Array, (x) => ('00' + x.toString(16)).slice(-2)) .join(''); var typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) { return parseInt(h, 16) })) var buffer = typedArray.buffer; return buffer; } private _clearHeart() { (this._hear_uuid != 0) && Framework.time.unschedule(this._hear_uuid); this._hear_uuid = 0; } private _startHeart() { this._clearHeart(); this._hear_uuid = Framework.time.schedule(() => { this._hear_time_cur += 1; if(this._hear_time_cur > this._hear_time_out){ console.error("心跳超时",this._hear_time_cur); this.close(true); //this._autoReconnect() } else if (this._socket) { // this._hear_uuid = 0; this.netApiSend("user","heart_beat",{}); } }, this._hear_time); } // 自动重连 // delay:延迟时间 private _autoReconnect(delay?:number) { if(this._bReconnect) { console.error("自动重连中",new Date()); return } if (this._is_connect) { return; } if (this._auto_reconnect_time > this._auto_reconnect_time_out) { Framework.tips.setTips("Reconnection failed"); console.error("多少次重连失败1") //window.parent.postMessage(FrameworkConf.Event.NET_ERROR, "*"); Framework.layer.open(ViewID.MaskUI,()=>{},{closeTime:0}); return; } delay = delay || 0 if(delay > 0){ Framework.time.scheduleOnce(()=>{ this._autoReconnect() },delay) return } console.log("自动重连"); this._auto_reconnect_time += 1; this._bReconnect = true this.connect(this._web_url,this._callback) } netApiSend(mod, act, args) { let req = { mod: mod, act: act, args: args, uid: this._uid, seq: this._seq++, } Framework.event.fireEvent('cid', args); // if(act != "heart_beat"){ // console.log("发送", req); // } this.send(req);// 握手消息,返回在netmanger里面处理 // 启动loading 遮罩id } }