quote.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { v4 } from 'uuid'
  2. import { useLoginStore } from '@/stores'
  3. import service from '@/services'
  4. import eventBus from '@/services/bus'
  5. import Socket from './build'
  6. import { RequestCode, MessageType } from './build/types'
  7. export default new (class {
  8. /** 行情链路 */
  9. private socket?: Socket;
  10. /** 行情订阅集合 */
  11. private subscribeMap = new Map<string, string[]>()
  12. private async connect() {
  13. if (!this.socket) {
  14. await service.onReady()
  15. const quoteUrl = service.getConfig('quoteUrl')
  16. this.socket = new Socket(quoteUrl, {
  17. heartbeat: true,
  18. })
  19. this.socket.onReconnect = () => {
  20. // 重新订阅商品
  21. this.subscribe()
  22. }
  23. this.socket.onPush = ({ data }) => {
  24. // 推送实时行情通知
  25. eventBus.$emit('QuotePush', data)
  26. }
  27. }
  28. return this.socket
  29. }
  30. /**
  31. * 开始行情订阅
  32. */
  33. private subscribe = () => {
  34. const subscribeData: string[] = []
  35. this.subscribeMap.forEach((list) => {
  36. subscribeData.push(...list)
  37. })
  38. if (subscribeData.length) {
  39. console.log('开始行情订阅', subscribeData)
  40. this.connect().then((ws) => {
  41. ws.send({
  42. headers: {
  43. requestId: v4(),
  44. requestCode: RequestCode.QuoteSubscribe,
  45. messageType: MessageType.Push,
  46. },
  47. data: subscribeData
  48. }).then((res) => {
  49. console.log('行情订阅成功', res)
  50. }).catch((err) => {
  51. console.error('行情订阅失败', err)
  52. })
  53. })
  54. } else {
  55. // 没有订阅的时候,断开连接
  56. this.close()
  57. }
  58. }
  59. /**
  60. * 添加行情订阅
  61. * @param goodsCodes
  62. * @param key
  63. * @returns
  64. */
  65. addSubscribe = (goodsCodes: string[], key?: string) => {
  66. const loginStore = useLoginStore()
  67. const uuid = key ?? v4()
  68. const value = this.subscribeMap.get(uuid) ?? []
  69. const start = () => {
  70. if (loginStore.token) {
  71. // 对相同 key 订阅的商品进行合并处理
  72. this.subscribeMap.set(uuid, [...value, ...goodsCodes])
  73. this.subscribe()
  74. }
  75. }
  76. return {
  77. uuid,
  78. start,
  79. stop: () => {
  80. const flag = this.subscribeMap.delete(uuid)
  81. if (flag) {
  82. console.log('删除订阅', uuid)
  83. }
  84. if (loginStore.token) {
  85. this.subscribe()
  86. }
  87. return flag
  88. },
  89. }
  90. }
  91. /**
  92. * 删除行情订阅
  93. * @param keys
  94. */
  95. removeSubscribe = (...keys: string[]) => {
  96. if (keys.length) {
  97. keys.forEach((key) => {
  98. if (this.subscribeMap.delete(key)) {
  99. console.log('删除订阅', key)
  100. }
  101. })
  102. } else {
  103. console.log('取消订阅')
  104. this.subscribeMap.clear()
  105. }
  106. this.subscribe()
  107. }
  108. /**
  109. * 关闭行情链路
  110. */
  111. close() {
  112. this.socket?.close()
  113. }
  114. })