1 import { eventHub } from '@/common/utils' 2 3 export class WebSocketClient { 4 static STATUS = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'] 5 static MAX_RECONNECT_TIMES = 3 6 static RECONNECT_TIME_INTERVAL = 5000 7 8 constructor () { 9 this.wasClean = null // Boolean. 是否正常断开。一般异常断开时,该值为false 10 this.reconnectTimes = 0 // 第n次重连的flag 11 this.messageHandler = {} 12 this.createWebSocket() 13 Object.defineProperties(this, { 14 readyState: { 15 enumerable: true, 16 get: function () { 17 return this.ws && this.ws.readyState 18 } 19 }, 20 status: { 21 enumerable: true, 22 get: function () { 23 return (this.readyState && this.constructor.STATUS[this.readyState]) || 'UNCREATE' 24 } 25 } 26 }) 27 } 28 29 /** TODO: 30 * @param isReconnected 该参数暂未使用 31 */ 32 createWebSocket (isReconnected = false) { 33 if ('WebSocket' in window) { 34 if (!this.readyState || this.readyState === WebSocket.CLOSED) { 35 let protocol = location.protocol === 'https:' ? 'wss:' : 'ws:' 36 // Already include port 37 const host = location.host 38 const url = `${protocol}//${host}${process.env.VUE_APP_BASE_API}/api/ws` 39 40 this.ws = new WebSocket(url) 41 this.addEventsHandler() 42 } 43 } else { 44 alert('您的浏览器不支持 WebSocket!') 45 } 46 } 47 48 reconnectWebSocket (times = 0) { 49 if (times < WebSocketClient.MAX_RECONNECT_TIMES) { 50 console.log(`Try to reconnect the WebSocket after ${WebSocketClient.RECONNECT_TIME_INTERVAL / 1000} seconds.`) 51 setTimeout((t) => { 52 console.log(`${t + 1}th attempt to reconnect to WebSocket.`) 53 this.reconnectTimes++ 54 this.createWebSocket(true) 55 }, 5000, times) 56 } else { 57 console.error(`Could not create connection to Websocket server. Attempted reconnect ${WebSocketClient.MAX_RECONNECT_TIMES} times. Giving up.`) 58 } 59 } 60 61 addEventsHandler () { 62 this.ws.onopen = (event) => { 63 this.wasClean = null 64 this.reconnectTimes = 0 // 重连后重置 65 console.log('The Websocket has opened.') 66 this.send({ message: 'watch_capture', data: { sourceId: null, deployId: null } }) // hard code 67 } 68 this.ws.onmessage = (e) => { 69 const data = JSON.parse(e.data) 70 try { 71 if (data.message && this.messageHandler[data.message]) { 72 this.messageHandler[data.message](data) 73 } 74 } catch (e) { 75 console.warn(e) 76 } 77 // Trigger a data.message event on the eventHub 78 eventHub.$emit(data.message, data) 79 } 80 this.ws.onclose = (event) => { 81 this.wasClean = !!event.wasClean 82 if (this.wasClean) { 83 console.log('The WebSocket connection has been closed normally.', event) 84 } else { 85 console.error('closed', event) 86 } 87 } 88 this.ws.onerror = (err) => { 89 console.error('The WebSocket connection has been closed due to an error', err) 90 // this.ws = null 91 this.reconnectWebSocket(this.reconnectTimes) 92 } 93 } 94 95 registerHandler (msg, handle) { 96 const handler = {} 97 handler[msg] = handle 98 Object.assign(this.messageHandler, handler) 99 } 100 101 cancelRegister (msg) { 102 if (msg) { 103 delete this.messageHandler[msg] 104 } 105 } 106 107 /** 108 * 1. 判断当前websocket的连接状态为OPEN状态时发送消息 109 * 2. TODO: 当非OPEN状态时,判断是否为正常断开。当为异常断开时,重新连接,连接后再发送消息 110 * @param { object } msg 111 */ 112 send (msg) { 113 if (this.readyState === WebSocket.OPEN) { 114 this.ws.send(JSON.stringify(msg)) 115 } 116 } 117 118 close () { 119 this.ws.close() 120 } 121 }
自己封装的关于websocket的utils方法,仅供参考