| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- import { checkTokenAction, 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<Package40>;
- /** 交易长链 */
- trade: MTP2WebSocket<Package50>;
- }
- type LontLinkName = 'quote' | 'trade';
- /** 全局数据连接生命周期控制类 */
- export default new (class LifeCycleCtr {
- /** 数据中心 */
- private dataCenter = new DataCenter();
- /** 长链接管理 */
- public Socket: LongLink = {
- quote: new MTP2WebSocket<Package40>(0),
- trade: new MTP2WebSocket<Package50>(1),
- };
- 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<string> {
- if (this.Socket['quote'].connState === 0) {
- return this.connectServer('quote', serviceURL.quoteUrl).then(() => {
- // 开始发送心跳
- this.startBeatTime('quote');
- return 'ok';
- });
- } else {
- return Promise.resolve('已连接quote');
- }
- }
- /** 主动连接交易 */
- connectTrading(): Promise<string> {
- return this.connectServer('trade', serviceURL.tradeUrl).then(() => {
- // 开始发送心跳
- this.startBeatTime('trade');
- return 'ok';
- });
- // if (this.Socket['trade'].connState === 0) {
- // return this.connectServer('trade', serviceURL.tradeUrl);
- // } else {
- // return Promise.resolve('已连接trading');
- // }
- }
- /** 连接服务器 */
- connectServer(socket: LontLinkName, ws: string): Promise<string> {
- return new Promise((resolve, reject) => {
- this.Socket[socket].conn(ws);
- this.Socket[socket].onConnected = () => {
- console.info(`${socket},${ws},建立链接成功!`);
- resolve('ok');
- };
- this.Socket[socket].onClosed = () => {
- // 清空心跳定时器
- this.Socket[socket].stopBeatTimer(socket);
- console.error(`${socket},${ws},断开链接了!`);
- };
- this.Socket[socket].onError = (obj: MTP2WebSocket<Package40> | MTP2WebSocket<Package50>, err: Error) => {
- console.error(`${socket},${ws},发送错误:${err.message}`);
- reject(err);
- };
- if (socket === 'quote') this.quoteRelevant(this.Socket[socket]);
- if (socket === 'trade') this.tradingRelevant(this.Socket[socket]);
- });
- }
- /** 发送心跳 */
- startBeatTime(socket: LontLinkName): void {
- this.Socket[socket].startBeatTime(socket);
- this.Socket[socket].canReconnect = true;
- }
- /** 向交易服务器发送请求 */
- 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<Package40>) {
- // 推送信息
- socket.onReceivePush = (obj, msg: Package40) => {
- eventBus.$emit('quoteReceiveNtf', msg.content);
- };
- // 重连成功回调
- socket.onReconnectChangeState = (obj: MTP2WebSocket<Package40>, state) => {
- switch (state) {
- /** 开始重连 */
- case ReconnectChangeState.BeginReconnect:
- // 停止 token 校验
- // stopCheckToken()
- console.log(obj.host, '开始尝试重连服务端');
- break;
- /** 尝试重连失败,将在下一个周期后再次尝试重连 */
- case ReconnectChangeState.FailAndWaitPeriod:
- console.log(obj.host, '尝试重连失败,将在下一个周期后再次尝试重连');
- break;
- /** 重连成功,将进行业务操作 */
- case ReconnectChangeState.ReconnectSuccessed:
- console.log(obj.host, '重连成功,可开始进行业务操作');
- // 通知上层 重新订阅商品
- eventBus.$emit('quoteReconnectSucess', true);
- break;
- /** 重连成功后业务操作失败并将再次重试,由业务模块发起 */
- case ReconnectChangeState.LoginFail:
- break;
- /** 重连成功后业务操作成功(包括交易服务的账户登录状态更新或行情服务的行情订阅等 */
- case ReconnectChangeState.Logined:
- // 重连成功继续校验token
- // checkTokenAction();
- console.log(obj.host, '重连成功后业务操作成功(包括交易服务的账户登录状态更新或行情服务的行情订阅等');
- // 行情链路重连成功后,需要通知上层 重新订阅商品
- break;
- }
- };
- }
- /** 处理交易相关信息 */
- tradingRelevant(socket: MTP2WebSocket<Package50>) {
- // eslint-disable-next-line @typescript-eslint/no-this-alias
- const _this = this
- // 推送信息
- 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.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;
- default:
- msg.funCode !== 0 && console.warn({ msg: '接收到通知:' + msg.funCode });
- break;
- }
- };
- // 重连成功回调
- socket.onReconnectChangeState = (obj: MTP2WebSocket<Package50>, state) => {
- switch (state) {
- /** 开始重连 */
- case ReconnectChangeState.BeginReconnect:
- // 停止 token 校验
- stopCheckToken()
- console.log(obj.host, '开始尝试重连服务端');
- break;
- /** 尝试重连失败,将在下一个周期后再次尝试重连 */
- case ReconnectChangeState.FailAndWaitPeriod:
- console.log(obj.host, '尝试重连失败,将在下一个周期后再次尝试重连');
- break;
- /** 重连成功,将进行业务操作 */
- case ReconnectChangeState.ReconnectSuccessed:
- //重新发起心跳
- _this.startBeatTime('trade');
- // 重新启动定时 token 校验
- checkTokenAction()
- console.log(obj.host, '重连成功,将进行业务操作');
- break;
- /** 重连成功后业务操作失败并将再次重试,由业务模块发起 */
- case ReconnectChangeState.LoginFail:
- break;
- /** 重连成功后业务操作成功(包括交易服务的账户登录状态更新或行情服务的行情订阅等 */
- case ReconnectChangeState.Logined:
- break;
- }
- };
- }
- })();
|