|
@@ -1,55 +1,92 @@
|
|
|
import website from '~src/config/index'
|
|
|
-import { isNullES } from 'js-fast-way'
|
|
|
+import { getObjValue, isNullES } from 'js-fast-way'
|
|
|
|
|
|
// 长链接推送插件
|
|
|
-export default class HcSocket {
|
|
|
+class HcSocket {
|
|
|
|
|
|
- static socket = null
|
|
|
- static create(data, change) {
|
|
|
- const socket = new WebSocket(website.socket + data)
|
|
|
- socket.onopen = function () {
|
|
|
- console.log('websocket 链接成功')
|
|
|
+ constructor(data, change) {
|
|
|
+ this.limit = 30
|
|
|
+ this.interval = 10000
|
|
|
+ this.param = getObjValue(data)
|
|
|
+ this.onChange = change
|
|
|
+ this.socket = null
|
|
|
+ this.create()
|
|
|
+ this.moreTabs()
|
|
|
+ }
|
|
|
+
|
|
|
+ //创建连接
|
|
|
+ create() {
|
|
|
+ const { projectId, contractId, userId } = this.param
|
|
|
+ const { socket: socketUrl, clientId } = website
|
|
|
+
|
|
|
+ if (isNullES(socketUrl) || isNullES(clientId) || isNullES(projectId) || isNullES(contractId) || isNullES(userId)) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //拼接URL并登录socket
|
|
|
+ const url = `${socketUrl}/blade-${clientId}/${projectId}/${contractId}/${userId}`
|
|
|
+ this.socket = new WebSocket(url)
|
|
|
+
|
|
|
+ this.socket.onopen = ()=> {
|
|
|
+ console.log('WebSocket 链接成功')
|
|
|
}
|
|
|
- socket.onclose = function () {
|
|
|
- console.log('websocket 链接已断开')
|
|
|
+
|
|
|
+ this.socket.onclose = async () => {
|
|
|
+ console.log('WebSocket 链接已断开')
|
|
|
+ await this.reconnect()
|
|
|
}
|
|
|
- socket.onmessage = function ({ data }) {
|
|
|
- if (typeof change !== 'function') {
|
|
|
- return false
|
|
|
- } else {
|
|
|
- change(data)
|
|
|
+
|
|
|
+ this.socket.onmessage = ({ data })=> {
|
|
|
+ try {
|
|
|
+ const parsedData = JSON.parse(data)
|
|
|
+ if (typeof this.onChange === 'function') {
|
|
|
+ this.onChange(parsedData)
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('解析 WebSocket 数据时出错:', error)
|
|
|
}
|
|
|
}
|
|
|
- socket.onerror = function ({ data }) {
|
|
|
- console.log('websocket 发生错误:', data)
|
|
|
- }
|
|
|
- this.socket = socket
|
|
|
}
|
|
|
|
|
|
//发送消息
|
|
|
- static async send(data) {
|
|
|
- const is_socket = await this.isSocket()
|
|
|
- if (!is_socket) return false
|
|
|
+ async send(data) {
|
|
|
+ if (!this.isSocket()) return
|
|
|
this.socket.send(data)
|
|
|
}
|
|
|
|
|
|
//链接是否存在
|
|
|
- static async isSocket(i = 0) {
|
|
|
- let _this = this
|
|
|
- return new Promise((resolve) => {
|
|
|
- if (isNullES(_this.socket)) {
|
|
|
- if (i <= 30) {
|
|
|
- setTimeout(async () => {
|
|
|
- i++
|
|
|
- resolve(await _this.isSocket(i))
|
|
|
- }, 1000)
|
|
|
- } else {
|
|
|
- resolve(false)
|
|
|
- }
|
|
|
- } else {
|
|
|
- resolve(true)
|
|
|
+ isSocket() {
|
|
|
+ return !isNullES(this.socket) && (this.socket.readyState === WebSocket.OPEN)
|
|
|
+ }
|
|
|
+
|
|
|
+ //尝试重连
|
|
|
+ async reconnect(attempts = 0) {
|
|
|
+ if (attempts >= this.limit) return
|
|
|
+ if (isNullES(this.socket) || this.socket.readyState === WebSocket.CLOSED) {
|
|
|
+ this.create()
|
|
|
+ }
|
|
|
+ await new Promise(resolve => setTimeout(resolve, this.interval))
|
|
|
+ if (!this.isSocket()) {
|
|
|
+ await this.reconnect(attempts + 1)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理多标签页问题
|
|
|
+ moreTabs() {
|
|
|
+ document.addEventListener('visibilitychange', () => {
|
|
|
+ if (document.visibilityState === 'visible' && !this.isSocket()) {
|
|
|
+ this.create()
|
|
|
+ } else if (document.visibilityState === 'hidden') {
|
|
|
+ this.close()
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+ //关闭或断开连接
|
|
|
+ close() {
|
|
|
+ if (!this.isSocket()) return
|
|
|
+ this.socket.close()
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+export { HcSocket }
|