web
8 天以前 28ea77ec45bd860e23c0edfb6ee81a7d6599b25f
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/**
 * 监听报警
 * 跟后端建websorcket通信,监听设备返回参数,如果一直在变则正常,不用报警,如果参数不变就考虑是断电等情况,需要报警
 */
import { ElMessage } from 'element-plus'
import { getToken } from '@/utils/auth.js'
 
let wsUrl = '';
let socket = null;//实例对象
let lockReconnect = false; //是否真正建立连接
let timeout = 3 * 1000; //3秒一次心跳
let timeoutObj = null; //心跳倒计时
let serverTimeoutObj = null; //服务心跳倒计时
let timeoutnum = null; //断开 重连倒计时
 
// 初始
const initWebsocket = (url) => {
    if(url) wsUrl = url;
    if("WebSocket" in window) {
        socket = new WebSocket(wsUrl);
        socket.onerror = webSocketOnError;
        socket.onmessage = webSocketOnMessage;
        socket.onclose = closeWebsocket;
        socket.onopen = openWebsocket;
    } else {
        ElMessage.warning('你的浏览器不支持websocket,请更换浏览器')
    }
}
 
//建立连接
const openWebsocket = (e) => {
    start();
}
 
const start = ()=> {
    //开启心跳
    timeoutObj && clearTimeout(timeoutObj);
    serverTimeoutObj && clearTimeout(serverTimeoutObj);
    timeoutObj = setTimeout(function() {
        //这里发送一个心跳,后端收到后,返回一个心跳消息
        if (socket.readyState == 1) {
            //如果连接正常
            // socket.send("heartbeat");
        } else {
            //否则重连
            reconnect();
        }
        serverTimeoutObj = setTimeout(function() {
            //超时关闭
            socket.close();
        }, timeout);
    }, timeout);
}
 
//重置心跳
const reset =() => {
    //清除时间
    clearTimeout(timeoutObj);
    clearTimeout(serverTimeoutObj);
    //重启心跳
    start();
}
 
const sendWebsocket =(data) =>{
    socket.send(data);
}
 
//服务器返回的数据
const webSocketOnMessage=(e) => {
    //判断是否登录
    if (getToken()) {
        //window自定义事件,addEventListener监听onmessageWS事件
        window.dispatchEvent(
            new CustomEvent("onmessageWS", {
                detail: {
                    data: JSON.parse(e?.data),
                },
            })
        );
    }
    reset();
}
 
//重新连接
const reconnect =() => {
    if (lockReconnect) {
        return;
    }
    lockReconnect = true;
    //没连接上会一直重连,设置延迟避免请求过多
    timeoutnum && clearTimeout(timeoutnum);
    timeoutnum = setTimeout(function() {
        //新连接
        initWebsocket();
        lockReconnect = false;
    }, 1000);
}
 
//断开连接
const close =() => {
    //WebSocket对象也有发送和关闭的两个方法,只需要在自定义方法中分别调用send()和close()即可实现。
    socket.close();
}
 
const closeWebsocket=(e) => {
    reconnect();
}
 
const webSocketOnError =(e) => {
    reconnect();
 
}
 
 
export default { initWebsocket, sendWebsocket, webSocketOnMessage, close };