xieb
2023-09-13 3667807a7b7418efc090ee3fa6a6b734bc3080bf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import { message } from 'ant-design-vue'
import ReconnectingWebSocket from 'reconnecting-websocket'
import { ELocalStorageKey } from '../types'
 
interface WebSocketOptions {
  data: any
  cache?: boolean | string
  destroyCache?: string
}
 
export interface MessageHandler {
  (data : {[key: string]: any}): void
}
 
/**
 * ConnectWebSocket 类
 * TODO: 优化messageHandler: EventEmitter。暂时传入回调函数
 */
class ConnectWebSocket {
  _url: string
  _socket: ReconnectingWebSocket | null
  _hasInit: boolean
  _messageHandler: MessageHandler | null
 
  constructor (url: string) {
    this._url = url
    this._socket = null
    this._hasInit = false
    this._messageHandler = null
  }
 
  initSocket () {
    if (this._hasInit) {
      return
    }
    if (!this._url) {
      return
    }
    // 会自动重连,无需处理重连逻辑
    this._socket = new ReconnectingWebSocket(this._url, [], {
      maxReconnectionDelay: 20000, // 断开后最大的重连时间: 20s,每多一次重连,会增加 1.3 倍,5 * 1.3 * 1.3 * 1.3...
      minReconnectionDelay: 5000, // 断开后最短的重连时间: 5s
      maxRetries: 5,
    })
    this._hasInit = true
 
    this._socket.addEventListener('open', this._onOpen.bind(this))
    this._socket.addEventListener('close', this._onClose.bind(this))
    this._socket.addEventListener('error', this._onError.bind(this))
    this._socket.addEventListener('message', this._onMessage.bind(this))
  }
 
  _onOpen () {
    console.log('连接成功')
  }
 
  _onClose () {
    console.log('连接已断开')
  }
 
  _onError () {
    console.log('连接 error')
  }
 
  registerMessageHandler (messageHandler: MessageHandler) {
    this._messageHandler = messageHandler
  }
 
  _onMessage (msg: MessageEvent) {
    const data = JSON.parse(msg.data)
    this._messageHandler && this._messageHandler(data)
    console.log('接受消息', msg)
  }
 
  sendMessage = (message: WebSocketOptions): void => {
    this._socket?.send(JSON.stringify(message.data))
  }
 
  close () {
    this._socket?.close()
  }
}
 
export default ConnectWebSocket