123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409 |
- // import { Notifications } from '../notifications';
- import { Http } from "./weHttp";
- class networkMgr {
- ////////////////////////////
- // 类成员
- ///////////////////////////
- public static readonly _instance = new networkMgr();
- /** 消息ID */
- private mid = 0;
- /** 消息队列 */
- private messageList: any = {};
- /** 每条消息最多的发送次数 */
- private limitMessageNum = 5;
- /** 时间 */
- private timer: number | null = null;
- /** token */
- private token = '';
- /** 消息锁: false, 可以正常发送消息,已上锁 */
- private isLock = false;
- private _dealHeadListener: Function | null = null;
- /** 加密规则 */
- private _encryptRule = ['mid:', 'uid:', 'key:', 'data:'];
- /** 加密code, 服务端客户端要统一 */
- private _encryptCode = 'zqkg';
- /** 计时时间: 1s */
- private _intervalTime = 3000;
- /** 服务器报错 */
- private _errorServerCode = 500;
- /** 成功回包code */
- private _successCode = 0;
- /** 重起游戏的错误码 */
- private _errorRestartGameCode = [102];
- /** 错误码列表 */
- private _errorNetCode: any = {};
- /** 超过时间 */
- private _overTime = 5000;
- /** uid */
- private _uid = 0;
- private lastMessage = null;
- ////////////////////////////
- // get、set构造器
- ///////////////////////////
- public set errorNetCode(codes: Object) {
- this._errorNetCode = codes;
- }
- public set encryptCode(str: string) {
- this._encryptCode = str;
- }
- public set errorRestartGameCode(array: Array<number>) {
- this._errorRestartGameCode = array;
- }
- public set successCode(code: number) {
- this._successCode = code;
- }
- public set errorServerCode(code: number) {
- this._errorServerCode = code;
- }
- public set encryptRule(array: Array<string>) {
- this._encryptRule = array;
- }
- public set intervalTime(time: number) {
- this._intervalTime = time;
- }
- public set overTime(time: number) {
- this._overTime = time;
- }
- public set dealHeadListener(cb: Function) {
- this._dealHeadListener = cb;
- }
- public set uid(uid: number) {
- this._uid = uid;
- }
- ////////////////////////////
- // 接口
- ///////////////////////////
- public constructor() {
- this.mid = 0;
- this.messageList = {};
- this.timer = null;
- }
- /**
- * @description 发送xhr消息
- * @param {string} _route
- * @param {Object} data
- * @param {Function} cb
- * @param isRepeat 是否重复发送事件
- * @param fail 失败回调
- */
- public xhrPost(_route: string, data: Object, cb?: Function, fail?: Function, isRepeat = false) {
- this.mid += 1;
- // 包
- let msg = {
- head: {
- route: _route,
- mid: this.mid.toString(),
- uid: this._uid
- },
- body: data
- };
- // 消息队列的数据结构
- let netPackage = new NetworkPackage();
- netPackage.route = _route;
- netPackage.mid = this.mid;
- netPackage.data = msg;
- if (cb) {
- netPackage.callback = cb;
- }
- netPackage.isRepeat = isRepeat;
- if (fail) {
- netPackage.failCallBack = fail;
- }
- this.messageList[this.mid] = netPackage;
- // 开始计时
- this.startTimer();
- if (!this.isLock) {
- this.sendMessage(this.mid);
- }
- }
- /**
- * @description 检查回包
- * @param _respone
- */
- public checkRespone(route: any, _respone: any, mid: any) {
- // 解密
- let respone: any = this.jsdecrypt(_respone);
- let data = respone;
- // if (respone.result) {
- // data = this.jsdecrypt(respone.result);
- // }
- // respone = this.jsdecrypt(respone);
- // let head: any = respone.head;
- // let body: any = respone.body;
- // let code = head.code || 0;
- // let mid = 0;
- // 刷新token
- // this.token = head.token;
- let message = this.messageList[mid];
- // 头部回包处理
- // this.succeedResponeHead(head);
- // 服务端回包,返回需要的数据
- // if (code === this._successCode) {
- this.succeedResponeBody(message, data, mid);
- // 服务端回包中出现错误码
- // } else {
- // this.checkErrorCode(code, mid);
- // }
- }
- private succeedResponeHead(head: any) {
- if (this._dealHeadListener)
- this._dealHeadListener(head);
- }
- ////////////////////////////
- // 业务逻辑
- ///////////////////////////
- /**
- * @description 没有错误信息,把服务端数据发送到业务逻辑层
- * @param message
- * @param body
- * @param mid
- */
- private succeedResponeBody(message: any, body: any, mid: number) {
- this.isLock = false;
- this.clearTimer();
- this.deleteMessageListItem(mid, false);
- this.checkNextMessage();
- if (message && message.callback) {
- message.callback(body);
- }
- }
- /**
- * @description 网络消息code检查
- * @param code 错误码;需要和服务端协定
- * @param mid
- */
- private checkErrorCode(code: number, mid: number) {
- // 收到消息500 则继续重发直到发送次数限制.
- if (code !== this._errorServerCode) {
- this.deleteMessageListItem(mid, true);
- }
- // 重启游戏
- for (let index = 0; index < this._errorRestartGameCode.length; index++) {
- let errorCode = this._errorRestartGameCode[index];
- if (code === errorCode) {
- this.restartGame();
- }
- }
- let resultStr = this.getErrorCodeMeaning(code);
- console.error("----> 返回错误, code:", code, resultStr);
- // TODO: 把错误码信息返回给业务逻辑
- // Notifications.emit('sys_http_error', { code: code, mid: mid });
- }
- private checkNextMessage() {
- for (let key in this.messageList) {
- let message = this.messageList[key];
- if (message.sendNum === 0) {
- this.sendMessage(message.mid);
- }
- }
- }
- /**
- * @description 删除消息队列中的元素
- * @param mid
- * @param fail 是否是失败
- */
- private deleteMessageListItem(mid: number, fail: boolean) {
- if (this.messageList && this.messageList[mid]) {
- if (this.messageList[mid].failCallBack && fail) {
- this.messageList[mid].failCallBack();
- }
- delete this.messageList[mid];
- }
- }
- /**
- * @description 数据加密(需要和服务端约定)
- * @param data
- // */
- // private jsencrypt(data: any) {
- // // let head = data.head;
- // // let body = JSON.stringify(data.body);
- // // let encryptData = `${this._encryptRule[0]}${head.mid}&${this._encryptRule[1]}${head.uid}&${this._encryptRule[2]}${this._encryptCode}&${this._encryptRule[3]}${body}`;
- // // data.head.mi = Sha1.hex_hmac_sha1(this._encryptCode, encryptData).slice(5);
- // return data;
- // }
- /**
- * @description 解密
- * @param _data
- */
- private jsdecrypt(_data: any) {
- let obj = null;
- if (typeof _data == 'string') {
- try {
- obj = JSON.parse(_data);
- } catch (e) {
- }
- }
- // if (obj.result && obj) {
- // obj.result = window.DES3.decrypt(global.DES3_KEY, obj.result);
- // }
- return obj;
- }
- /**
- * @description 发送消息队列
- * @param {number} mid
- * @param {number} isCheck 是否检查包的发送次数是否超过上限
- */
- private sendMessage(mid: number, isCheck: boolean = true) {
- // 消息队列为空
- if (Object.keys(this.messageList).length === 0) {
- console.log('message list is null...');
- return;
- }
- let message = this.messageList[mid];
- // 一条消息的发送次数大于限制次数,建议重启游戏
- if (isCheck && message.sendNum >= this.limitMessageNum
- || !isCheck && message.errorNum >= this.limitMessageNum) {
- console.error(message.data.head.route, 'message send too much times');
- this.deleteMessageListItem(mid, false);
- // Notifications.emit('sys_http_try_too_many_time');
- return;
- }
- message.sendNum += 1;
- let data = message.data;
- let route = data.head.route;
- data.head.token = this.token;
- // 加密
- console.log('----> 请求数据', route, data.body);
- this.lastMessage = message;
- Http.post(route, data.body, mid);
- }
- /**
- * @description 获取错误码对应的意思
- * @param code
- */
- private getErrorCodeMeaning(code: number) {
- let errStr = this._errorNetCode[code];
- let resultStr = errStr;
- if (!errStr) {
- resultStr = `服务器错误码: ${code}`;
- }
- return resultStr;
- }
- /**
- * @description 重起游戏
- */
- private restartGame() {
- }
- /**
- * @description 开始定时器
- */
- private startTimer() {
- if (!this.timer) {
- this.timer = setInterval(this.checkPackage.bind(this), this._intervalTime);
- }
- }
- /**
- * @description 检查发包
- */
- private checkPackage() {
- if (Object.keys(this.messageList).length !== 0) {
- for (let key in this.messageList) {
- let message = this.messageList[key];
- let time = Date.now();
- if (time - message.time > this._overTime && message.isRepeat) {
- let mid = message.mid;
- this.sendMessage(mid);
- break;
- } else {
- this.deleteMessageListItem(message.mid, false);
- }
- }
- } else {
- this.clearTimer();
- }
- }
- /**
- * @description 清理定时器
- */
- private clearTimer() {
- if (this.timer) {
- clearInterval(this.timer);
- this.timer = 0;
- }
- }
- /**
- * http请求err处理
- * @param mid 消息id
- * @param error 错误内容
- * @param tip 错误提示文本
- */
- public onHttpError(mid: any, error?: any, tip?: string): void {
- if (tip)
- console.error("----> onHttpError", tip, error);
- else
- console.error("----> onHttpError", error);
- let pack: NetworkPackage = this.messageList[mid];
- if (pack) {
- //如果需要重复
- if (pack.isRepeat) {
- setTimeout(() => {
- pack.errorNum++
- this.sendMessage(mid, false);
- }, 3000);
- } else {
- this.deleteMessageListItem(mid, true);
- }
- }
- };
- }
- export const NetworkMgr = networkMgr._instance;
- /**
- * NetworkPackage
- * 网络包
- */
- // main
- export default class NetworkPackage {
- public route: string = '';
- public lock: boolean = false;
- public mid: number = 0;
- public data: any = null;
- /**接口成功回调 */
- public callback: Function | null = null;
- /**接口失败回调 */
- public failCallBack: Function | null = null;
- public time: number = 0;
- public sendNum: number = 0;
- public errorNum: number = 0;
- /**是否重复调用 */
- public isRepeat: boolean = false;
- public constructor(msg?: any) {
- this.time = Date.now();
- for (let key in msg) {
- let that = this as any
- that[key] = msg[key];
- }
- }
- };
|