123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- import website from '~src/config/index'
- import { getObjValue, isNullES } from 'js-fast-way'
- // 长链接推送插件
- class HcSocket {
- constructor(data, change, open) {
- this.limit = website.socketLimit
- this.interval = website.socketInterval
- this.param = getObjValue(data)
- this.onChange = change
- this.onSocketOpen = open
- this.socket = null
- this.isReconnecting = false
- this.connectionStatus = 'disconnected'
- this.isManualClosed = false
- if (this.validateParams()) {
- this.create()
- //this.handleMultipleTabs()
- }
- }
- validateParams() {
- const { projectId, contractId, userId } = this.param
- const { socket: socketUrl, clientId } = website
- return !(isNullES(socketUrl) || isNullES(clientId) || isNullES(projectId) || isNullES(contractId) || isNullES(userId))
- }
- //创建连接
- create() {
- const { projectId, contractId, userId } = this.param
- const { socket: socketUrl, clientId } = website
- const url = `${socketUrl}/${clientId}/${projectId}/${contractId}/${userId}`
- this.socket = new WebSocket(url)
- this.socket.onopen = this.handleOpen.bind(this)
- this.socket.onclose = this.handleClose.bind(this)
- this.socket.onmessage = this.handleMessage.bind(this)
- this.socket.onerror = this.handleError.bind(this)
- }
- handleOpen() {
- console.log('WebSocket 链接成功')
- this.connectionStatus = 'connected'
- this.isManualClosed = false
- if (typeof this.onSocketOpen === 'function' && this.onSocketOpen) {
- this.onSocketOpen()
- }
- }
- handleClose() {
- console.log('WebSocket 链接已断开')
- this.connectionStatus = 'disconnected'
- if (!this.isManualClosed) {
- this.reconnect()
- }
- }
- handleMessage({ data }) {
- try {
- const parsedData = JSON.parse(data)
- if (typeof this.onChange === 'function') {
- this.onChange(parsedData)
- }
- } catch (error) {
- console.error('解析 WebSocket 数据时出错:', error)
- }
- }
- handleError(error) {
- console.error('WebSocket 错误:', error)
- this.connectionStatus = 'error'
- }
- //发送消息
- send(data) {
- if (this.isSocket()) {
- this.socket.send(data)
- } else {
- console.warn('消息发送失败')
- }
- }
- //链接是否存在
- isSocket() {
- return !isNullES(this.socket) && (this.socket.readyState === WebSocket.OPEN)
- }
- //尝试重连
- async reconnect(attempts = 0) {
- if (this.isReconnecting || this.isManualClosed) return
- this.isReconnecting = true
- while (attempts < this.limit && !this.isSocket() && !this.isManualClosed) {
- console.log(`重新链接中... (${attempts + 1}/${this.limit})`)
- this.create()
- await new Promise(resolve => setTimeout(resolve, this.interval))
- attempts++
- }
- this.isReconnecting = false
- if (!this.isSocket() && !this.isManualClosed) {
- console.error('达到最大重连次数后仍然失败')
- }
- }
- handleMultipleTabs() {
- document.addEventListener('visibilitychange', this.handleVisibilityChange.bind(this))
- }
- // 处理多标签页问题
- handleVisibilityChange() {
- if (document.visibilityState === 'visible' && !this.isSocket() && !this.isManualClosed) {
- this.create()
- } else if (document.visibilityState === 'hidden') {
- this.close()
- }
- }
- //关闭或断开连接
- close() {
- this.isManualClosed = true
- if (this.isSocket()) {
- this.socket.close()
- }
- this.connectionStatus = 'disconnected'
- }
- destroy() {
- this.close()
- //document.removeEventListener('visibilitychange', this.handleVisibilityChange)
- this.socket = null
- this.onChange = null
- }
- }
- export { HcSocket }
|