import { handleTokenCheck, checkTokenLoop, stopCheckToken } from '@/services/bus/token'; import { NeedClearSourceDataType, NoClearSourceDataType } from '@/services/dataCenter/interface'; import { funCode } from '@/services/funcode/index'; import { serviceURL } from '@/services/request/index'; import timerUtil from '@/utils/timer/timerUtil'; import { Callback, MTP2WebSocket, ReconnectChangeState } from '@/utils/websocket/index'; import { Package40, Package50 } from '@/utils/websocket/package'; import eventBus from '../utils/eventBus'; import DataCenter from './dataCenter/index'; import { noticeParseRsp } from './socket/protobuf/buildReq'; /** 行情和交易长链 */ interface LongLink { /** 行情长链 */ quote: MTP2WebSocket; /** 交易长链 */ trade: MTP2WebSocket; } type LontLinkName = 'quote' | 'trade'; /** 全局数据连接生命周期控制类 */ export default new (class LifeCycleCtr { /** 数据中心 */ private dataCenter = new DataCenter(); /** 长链接管理 */ public Socket: LongLink = { quote: new MTP2WebSocket('quote'), trade: new MTP2WebSocket('trade'), }; constructor() { } /** 数据中心初始化 */ initDataCenter(): void { } /** * 从数据中心获取普通数据 * @param key needClearSourceDataType | noClearSourceDataType */ get(key: keyof (NeedClearSourceDataType & NoClearSourceDataType)) { return this.dataCenter.getOneOf(key).value; } /** * 从数据中心获取数据响应式数据 * @param key needClearSourceDataType | noClearSourceDataType */ getRef(key: keyof (NeedClearSourceDataType & NoClearSourceDataType)) { return this.dataCenter.getOneOf(key); } /** * 从数据中心获取所有数据 * @param key needClearSourceDataType | noClearSourceDataType */ reset() { this.dataCenter.reset(); } /** * 数据中心存入数据 * @param key needClearSourceDataType | noClearSourceDataType * @param value any */ set(key: keyof (NeedClearSourceDataType & NoClearSourceDataType), value: any) { return this.dataCenter.setOneOf(key, value); } /** 主动连接行情 */ connectQuote(): Promise { return this.connectServer('quote', serviceURL.quoteUrl); } /** 主动连接交易 */ connectTrading(): Promise { return this.connectServer('trade', serviceURL.tradeUrl); } /** 连接服务器 */ connectServer(socket: LontLinkName, ws: string): Promise { const service = this.Socket[socket]; return new Promise((resolve, reject) => { service.onError = (obj: MTP2WebSocket | MTP2WebSocket, err: Error) => { reject(err); } service.conn(ws).then(() => { resolve(socket); }) if (socket === 'quote') this.quoteRelevant(this.Socket[socket]); if (socket === 'trade') this.tradingRelevant(this.Socket[socket]); }) } /** 向交易服务器发送请求 */ sendTradingServer(p: Package50, rsp?: number, callback?: Callback): void { this.Socket['trade'].send(p, rsp, callback); } /** 向行情服务器发送请求 */ sendQuoteServer(p: Package40, rsp?: number, callback?: Callback): void { this.Socket['quote'].send(p, rsp, callback); } /** 主动关闭行情服务 */ closeQuote() { this.Socket['quote'].close(); } /** 主动关闭长链接 */ closeServer(): void { this.Socket['trade'].close(); this.dataCenter.reset(); // sessionStorage.clear(); // localStorageUtil.removeItem('loginData'); // timerUtil.clearAll(); } /** 处理行情相关信息 */ quoteRelevant(socket: MTP2WebSocket) { // 推送信息 socket.onReceivePush = (obj, msg: Package40) => { eventBus.$emit('quoteReceiveNtf', msg.content); }; // 重连成功回调 socket.onReconnectChangeState = (obj: MTP2WebSocket, state) => { switch (state) { /** 开始重连 */ case ReconnectChangeState.BeginReconnect: break; /** 尝试重连失败,将在下一个周期后再次尝试重连 */ case ReconnectChangeState.FailAndWaitPeriod: break; /** 重连成功,将进行业务操作 */ case ReconnectChangeState.ReconnectSuccessed: console.log(obj.host, '重连成功,可开始进行业务操作'); break; /** 重连成功后业务操作失败并将再次重试,由业务模块发起 */ case ReconnectChangeState.LoginFail: break; /** 重连成功后业务操作成功(包括交易服务的账户登录状态更新或行情服务的行情订阅等 */ case ReconnectChangeState.Logined: break; } }; } /** 处理交易相关信息 */ tradingRelevant(socket: MTP2WebSocket) { // 推送信息 socket.onReceivePush = (_self, msg) => { switch (msg.funCode) { case funCode.CustOfflineNtf: //接收到账户离线通知 eventBus.$emit('custOfflineNtf', noticeParseRsp(msg, 'CustOfflineNtf')); break; case funCode.LogoutRsp: // 接收到用户登出应答 eventBus.$emit('userLogout', noticeParseRsp(msg, 'LogoutRsp')); break; case funCode.MarketStatusChangeNtf: // 市场状态变更通知 eventBus.$emit('marketStatusChangeNtf', noticeParseRsp(msg, 'MarketStatusChangeNtf')); break; case funCode.PosChangedNtf: //接收到头寸变化通知! eventBus.$emit('posChangedNtf', noticeParseRsp(msg, 'PosChangedNtf')); break; case funCode.MoneyChangedNtf: // 接收到资金变化通知 eventBus.$emit('moneyChangedNtf', noticeParseRsp(msg, 'MoneyChangedNtf')); break; case funCode.OrderCanceledNtf: // 接收到委托单撤单通知 eventBus.$emit('orderCanceledNtf', noticeParseRsp(msg, 'OrderCanceledNtf')); break; case funCode.WRTradeDealedNtf: // 接收到仓单贸易成交通知 eventBus.$emit('wrTradeDealedNtf', noticeParseRsp(msg, 'WRTradeDealedNtf')); break; default: msg.funCode !== 0 && console.warn({ msg: '接收到未定义通知:' + msg.funCode }); break; } }; // 重连成功回调 socket.onReconnectChangeState = (obj: MTP2WebSocket, state) => { switch (state) { /** 开始重连 */ case ReconnectChangeState.BeginReconnect: // 停止 token 校验 stopCheckToken() break; /** 尝试重连失败,将在下一个周期后再次尝试重连 */ case ReconnectChangeState.FailAndWaitPeriod: break; /** 重连成功,将进行业务操作 */ case ReconnectChangeState.ReconnectSuccessed: // 重新启动定时 token 校验 handleTokenCheck().then(() => { checkTokenLoop(); }) console.log(obj.host, '重连成功,将进行业务操作'); break; /** 重连成功后业务操作失败并将再次重试,由业务模块发起 */ case ReconnectChangeState.LoginFail: break; /** 重连成功后业务操作成功(包括交易服务的账户登录状态更新或行情服务的行情订阅等 */ case ReconnectChangeState.Logined: break; } }; } })();