index.ts 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. import { handleTokenCheck, checkTokenLoop, stopCheckToken } from '@/services/bus/token';
  2. import { NeedClearSourceDataType, NoClearSourceDataType } from '@/services/dataCenter/interface';
  3. import { funCode } from '@/services/funcode/index';
  4. import { serviceURL } from '@/services/request/index';
  5. import timerUtil from '@/utils/timer/timerUtil';
  6. import { Callback, MTP2WebSocket, ReconnectChangeState } from '@/utils/websocket/index';
  7. import { Package40, Package50 } from '@/utils/websocket/package';
  8. import eventBus from '../utils/eventBus';
  9. import DataCenter from './dataCenter/index';
  10. import { noticeParseRsp } from './socket/protobuf/buildReq';
  11. /** 行情和交易长链 */
  12. interface LongLink {
  13. /** 行情长链 */
  14. quote: MTP2WebSocket<Package40>;
  15. /** 交易长链 */
  16. trade: MTP2WebSocket<Package50>;
  17. }
  18. type LontLinkName = 'quote' | 'trade';
  19. /** 全局数据连接生命周期控制类 */
  20. export default new (class LifeCycleCtr {
  21. /** 数据中心 */
  22. private dataCenter = new DataCenter();
  23. /** 长链接管理 */
  24. public Socket: LongLink = {
  25. quote: new MTP2WebSocket<Package40>('quote'),
  26. trade: new MTP2WebSocket<Package50>('trade'),
  27. };
  28. constructor() { }
  29. /** 数据中心初始化 */
  30. initDataCenter(): void { }
  31. /**
  32. * 从数据中心获取普通数据
  33. * @param key needClearSourceDataType | noClearSourceDataType
  34. */
  35. get(key: keyof (NeedClearSourceDataType & NoClearSourceDataType)) {
  36. return this.dataCenter.getOneOf(key).value;
  37. }
  38. /**
  39. * 从数据中心获取数据响应式数据
  40. * @param key needClearSourceDataType | noClearSourceDataType
  41. */
  42. getRef(key: keyof (NeedClearSourceDataType & NoClearSourceDataType)) {
  43. return this.dataCenter.getOneOf(key);
  44. }
  45. /**
  46. * 从数据中心获取所有数据
  47. * @param key needClearSourceDataType | noClearSourceDataType
  48. */
  49. reset() {
  50. this.dataCenter.reset();
  51. }
  52. /**
  53. * 数据中心存入数据
  54. * @param key needClearSourceDataType | noClearSourceDataType
  55. * @param value any
  56. */
  57. set(key: keyof (NeedClearSourceDataType & NoClearSourceDataType), value: any) {
  58. return this.dataCenter.setOneOf(key, value);
  59. }
  60. /** 主动连接行情 */
  61. connectQuote(): Promise<string> {
  62. return this.connectServer('quote', serviceURL.quoteUrl);
  63. }
  64. /** 主动连接交易 */
  65. connectTrading(): Promise<string> {
  66. return this.connectServer('trade', serviceURL.tradeUrl);
  67. }
  68. /** 连接服务器 */
  69. connectServer(socket: LontLinkName, ws: string): Promise<string> {
  70. const service = this.Socket[socket];
  71. return new Promise((resolve, reject) => {
  72. service.onError = (obj: MTP2WebSocket<Package40> | MTP2WebSocket<Package50>, err: Error) => {
  73. reject(err);
  74. }
  75. service.conn(ws).then(() => {
  76. resolve(socket);
  77. })
  78. if (socket === 'quote') this.quoteRelevant(this.Socket[socket]);
  79. if (socket === 'trade') this.tradingRelevant(this.Socket[socket]);
  80. })
  81. }
  82. /** 向交易服务器发送请求 */
  83. sendTradingServer(p: Package50, rsp?: number, callback?: Callback): void {
  84. this.Socket['trade'].send(p, rsp, callback);
  85. }
  86. /** 向行情服务器发送请求 */
  87. sendQuoteServer(p: Package40, rsp?: number, callback?: Callback): void {
  88. this.Socket['quote'].send(p, rsp, callback);
  89. }
  90. /** 主动关闭行情服务 */
  91. closeQuote() {
  92. this.Socket['quote'].close();
  93. }
  94. /** 主动关闭长链接 */
  95. closeServer(): void {
  96. this.Socket['trade'].close();
  97. this.dataCenter.reset();
  98. // sessionStorage.clear();
  99. // localStorageUtil.removeItem('loginData');
  100. // timerUtil.clearAll();
  101. }
  102. /** 处理行情相关信息 */
  103. quoteRelevant(socket: MTP2WebSocket<Package40>) {
  104. // 推送信息
  105. socket.onReceivePush = (obj, msg: Package40) => {
  106. eventBus.$emit('quoteReceiveNtf', msg.content);
  107. };
  108. // 重连成功回调
  109. socket.onReconnectChangeState = (obj: MTP2WebSocket<Package40>, state) => {
  110. switch (state) {
  111. /** 开始重连 */
  112. case ReconnectChangeState.BeginReconnect:
  113. break;
  114. /** 尝试重连失败,将在下一个周期后再次尝试重连 */
  115. case ReconnectChangeState.FailAndWaitPeriod:
  116. break;
  117. /** 重连成功,将进行业务操作 */
  118. case ReconnectChangeState.ReconnectSuccessed:
  119. console.log(obj.host, '重连成功,可开始进行业务操作');
  120. break;
  121. /** 重连成功后业务操作失败并将再次重试,由业务模块发起 */
  122. case ReconnectChangeState.LoginFail:
  123. break;
  124. /** 重连成功后业务操作成功(包括交易服务的账户登录状态更新或行情服务的行情订阅等 */
  125. case ReconnectChangeState.Logined:
  126. break;
  127. }
  128. };
  129. }
  130. /** 处理交易相关信息 */
  131. tradingRelevant(socket: MTP2WebSocket<Package50>) {
  132. // 推送信息
  133. socket.onReceivePush = (_self, msg) => {
  134. switch (msg.funCode) {
  135. case funCode.CustOfflineNtf:
  136. //接收到账户离线通知
  137. eventBus.$emit('custOfflineNtf', noticeParseRsp(msg, 'CustOfflineNtf'));
  138. break;
  139. case funCode.LogoutRsp:
  140. // 接收到用户登出应答
  141. eventBus.$emit('userLogout', noticeParseRsp(msg, 'LogoutRsp'));
  142. break;
  143. case funCode.MarketStatusChangeNtf:
  144. // 市场状态变更通知
  145. eventBus.$emit('marketStatusChangeNtf', noticeParseRsp(msg, 'MarketStatusChangeNtf'));
  146. break;
  147. case funCode.PosChangedNtf:
  148. //接收到头寸变化通知!
  149. eventBus.$emit('posChangedNtf', noticeParseRsp(msg, 'PosChangedNtf'));
  150. break;
  151. case funCode.MoneyChangedNtf:
  152. // 接收到资金变化通知
  153. eventBus.$emit('moneyChangedNtf', noticeParseRsp(msg, 'MoneyChangedNtf'));
  154. break;
  155. case funCode.OrderCanceledNtf:
  156. // 接收到委托单撤单通知
  157. eventBus.$emit('orderCanceledNtf', noticeParseRsp(msg, 'OrderCanceledNtf'));
  158. break;
  159. case funCode.WRTradeDealedNtf:
  160. // 接收到仓单贸易成交通知
  161. eventBus.$emit('wrTradeDealedNtf', noticeParseRsp(msg, 'WRTradeDealedNtf'));
  162. break;
  163. default:
  164. msg.funCode !== 0 && console.warn({ msg: '接收到未定义通知:' + msg.funCode });
  165. break;
  166. }
  167. };
  168. // 重连成功回调
  169. socket.onReconnectChangeState = (obj: MTP2WebSocket<Package50>, state) => {
  170. switch (state) {
  171. /** 开始重连 */
  172. case ReconnectChangeState.BeginReconnect:
  173. // 停止 token 校验
  174. stopCheckToken()
  175. break;
  176. /** 尝试重连失败,将在下一个周期后再次尝试重连 */
  177. case ReconnectChangeState.FailAndWaitPeriod:
  178. break;
  179. /** 重连成功,将进行业务操作 */
  180. case ReconnectChangeState.ReconnectSuccessed:
  181. // 重新启动定时 token 校验
  182. handleTokenCheck().then(() => {
  183. checkTokenLoop();
  184. })
  185. console.log(obj.host, '重连成功,将进行业务操作');
  186. break;
  187. /** 重连成功后业务操作失败并将再次重试,由业务模块发起 */
  188. case ReconnectChangeState.LoginFail:
  189. break;
  190. /** 重连成功后业务操作成功(包括交易服务的账户登录状态更新或行情服务的行情订阅等 */
  191. case ReconnectChangeState.Logined:
  192. break;
  193. }
  194. };
  195. }
  196. })();