import { isDevMode } from '@/utils/env' import { message } from 'antd' import type { MessageType } from '@/types/typing' import wsNotice from '@/components/RightContent/Book/wsNotice' enum ReadyState { Connecting = 0, Open = 1, Closing = 2, Closed = 3 } export enum CmdType { /** @name 通知、消息 */ NoticeOrMessage = 13, /** @name 在线员工列表 */ OnlineBook = 12, /** @name 员工工作状态 */ WorkStatus = 14 } interface Options { // reconnectLimit?: number; // reconnectInterval?: number; onOpen?: (event: WebSocketEventMap['open']) => void onClose?: (event: WebSocketEventMap['close']) => void onMessage?: (message: WebSocketEventMap['message']) => void onError?: (event: WebSocketEventMap['error']) => void } class Ws { public uri: string // websocket 链接地址 public opts?: Options // websocket 链接相关配置 private isLock: boolean // 防止多次重连 public timeout?: number // ♥跳间隔时长 public wsIns: WebSocket | undefined // websocket实例 // 初始化socket,一般在应用启动时初始化一次就好了,或者需要更换wsUrl public init(uri: string, opts?: Options) { this.uri = uri this.opts = opts this.connectWs() } // 利用promise封装,解决ws可能没有实例化 public getInstance(): Promise { return new Promise((resolve, reject) => { if (this.wsIns?.readyState === ReadyState.Open) { resolve(this.wsIns) } else if (this.wsIns) { this.connectWs() resolve(this.wsIns) } else { reject() } }) } private connectWs() { try { this.wsIns = new WebSocket(this.uri) this.wsIns.onmessage = msg => { this.opts?.onMessage?.(JSON.parse(msg.data)) } this.wsIns.onclose = event => { this.opts?.onClose?.(event) } this.wsIns.onerror = err => { this.opts?.onError?.(err) } } catch (error) { // 未来要做心跳机制 if (isDevMode()) { message.error(error.toString()) } this.wsIns = undefined } } public sendMessage(map: MessageType) { if (this.wsIns?.readyState === ReadyState.Open) { this.wsIns.send(JSON.stringify(map)) } } public disconnect() { if (this.wsIns?.readyState === ReadyState.Open) { this.wsIns.close() } } } export function onMessage(msg: MessageType) { // 这里执行所有的message监听事件 switch (msg.cmd) { // 通知、消息 case CmdType.NoticeOrMessage: wsNotice(msg) break // 在线员工列表 case CmdType.OnlineBook: break default: break } } export default new Ws()