import { v4 } from 'uuid' import { useLoginStore } from '@/stores' import service from '@/services' import eventBus from '@/services/bus' import Socket from './build' import { RequestCode, MessageType } from './build/types' export default new (class { /** 行情链路 */ private socket?: Socket; /** 行情订阅集合 */ private subscribeMap = new Map() private async connect() { if (!this.socket) { await service.onReady() const quoteUrl = service.getConfig('quoteUrl') this.socket = new Socket(quoteUrl, { heartbeat: true, }) this.socket.onReconnect = () => { // 重新订阅商品 this.subscribe() } this.socket.onPush = ({ data }) => { // 推送实时行情通知 eventBus.$emit('QuotePush', data) } } return this.socket } /** * 开始行情订阅 */ private subscribe = () => { const subscribeData: string[] = [] this.subscribeMap.forEach((list) => { subscribeData.push(...list) }) if (subscribeData.length) { console.log('开始行情订阅', subscribeData) this.connect().then((ws) => { ws.send({ headers: { requestId: v4(), requestCode: RequestCode.QuoteSubscribe, messageType: MessageType.Push, }, data: subscribeData }).then((res) => { console.log('行情订阅成功', res) }).catch((err) => { console.error('行情订阅失败', err) }) }) } else { // 没有订阅的时候,断开连接 this.close() } } /** * 添加行情订阅 * @param goodsCodes * @param key * @returns */ addSubscribe = (goodsCodes: string[], key?: string) => { const loginStore = useLoginStore() const uuid = key ?? v4() const value = this.subscribeMap.get(uuid) ?? [] const start = () => { if (loginStore.token) { // 对相同 key 订阅的商品进行合并处理 this.subscribeMap.set(uuid, [...value, ...goodsCodes]) this.subscribe() } } return { uuid, start, stop: () => { const flag = this.subscribeMap.delete(uuid) if (flag) { console.log('删除订阅', uuid) } if (loginStore.token) { this.subscribe() } return flag }, } } /** * 删除行情订阅 * @param keys */ removeSubscribe = (...keys: string[]) => { if (keys.length) { keys.forEach((key) => { if (this.subscribeMap.delete(key)) { console.log('删除订阅', key) } }) } else { console.log('取消订阅') this.subscribeMap.clear() } this.subscribe() } /** * 关闭行情链路 */ close() { this.socket?.close() } })