#
zjj
2025-05-28 4722a49b9f09c18600b2e2bd849c418430d7f4d5
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
import { EventDispatcher } from './dispatcher';
 
export class WebSocketClient extends EventDispatcher {
    // #socket链接
    url = '';
    // #socket实例
    socket = null;
    // #重连次数
    reconnectAttempts = 0;
    // #最大重连数
    maxReconnectAttempts = 20;
    // #重连间隔
    reconnectInterval = 60000; // 10 seconds
    // #发送心跳数据间隔
    heartbeatInterval = 1000 * 30;
    // #计时器id
    heartbeatTimer = undefined;
    // #彻底终止ws
    stopWs = false;
    // *构造函数
    constructor(url) {
        super();
        this.url = url;
    }
    // >生命周期钩子
    onopen(callBack) {
        this.addEventListener('open', callBack);
    }
    onmessage(callBack) {
        this.addEventListener('message', callBack);
    }
    onclose(callBack) {
        this.addEventListener('close', callBack);
    }
    onerror(callBack) {
        this.addEventListener('error', callBack);
    }
    // >消息发送
    send(message) {
        if (this.socket && this.socket.readyState === WebSocket.OPEN) {
            this.socket.send({
                data:message,                
            });
        } else {
            console.error('[WebSocket] 未连接');
        }
    }
 
    // !初始化连接
    connect() {
        if (this.reconnectAttempts === 0) {
            this.log('WebSocket', `初始化连接中...          ${this.url}`);
        }
        if (this.socket && this.socket.readyState === WebSocket.OPEN) {
            return;
        }
        this.socket = uni.connectSocket({
            url: this.url,
            complete: ()=> {}
        });
        this.socket.onOpen((event)=>{            
            this.stopWs = false;
            // 重置重连尝试成功连接
            this.reconnectAttempts = 0;
            // 在连接成功时停止当前的心跳检测并重新启动
            this.startHeartbeat();            
            this.log('WebSocket', `连接成功,等待服务端数据推送[onopen]...     ${this.url}`);
            this.dispatchEvent('open', event);
        })
        // !websocket连接成功
        // this.socket.onOpen = event => {            
        //     this.stopWs = false;
        //     // 重置重连尝试成功连接
        //     this.reconnectAttempts = 0;
        //     // 在连接成功时停止当前的心跳检测并重新启动
        //     this.startHeartbeat();            
        //     this.log('WebSocket', `连接成功,等待服务端数据推送[onopen]...     ${this.url}`);
        //     this.dispatchEvent('open', event);
        // };
        this.socket.onMessage((event)=>{
            this.dispatchEvent('message', event);
            this.startHeartbeat();
        })
   //      this.socket.onMessage = event => {
            // console.log(event)
           // this.dispatchEvent('message', event);
           // this.startHeartbeat();
   //      };
        this.socket.onClose((event)=>{
            if (this.reconnectAttempts === 0) {
                this.log('WebSocket', `连接断开[onclose]...    ${this.url}`);
            }
            if (!this.stopWs) {
                this.handleReconnect();
            }
            this.dispatchEvent('close', event);
        })
        // this.socket.onClose = event => {
        //     if (this.reconnectAttempts === 0) {
        //         this.log('WebSocket', `连接断开[onclose]...    ${this.url}`);
        //     }
        //     if (!this.stopWs) {
        //         this.handleReconnect();
        //     }
        //     this.dispatchEvent('close', event);
        // };
        this.socket.onError((event)=>{
            if (this.reconnectAttempts === 0) {
                this.log('WebSocket', `连接异常[onerror]...    ${this.url}`);
            }
            if (!this.stopWs) {
                this.handleReconnect();
            }
            this.closeHeartbeat();
            this.dispatchEvent('error', event);
        })
        
        // uni.onSocketError((event)=>{
        //     console.log("333")
        //     if (this.reconnectAttempts === 0) {
        //         this.log('WebSocket', `连接异常[onerror]...    ${this.url}`);
        //     }
        //     if (!this.stopWs) {
        //         this.handleReconnect();
        //     }
        //     this.closeHeartbeat();
        //     this.dispatchEvent('error', event);
        // })
        // this.socket.onError = event => {
        //     if (this.reconnectAttempts === 0) {
        //         this.log('WebSocket', `连接异常[onerror]...    ${this.url}`);
        //     }
        //     this.closeHeartbeat();
        //     this.dispatchEvent('error', event);
        // };
    }
 
    // > 断网重连逻辑
    handleReconnect() {
        if (this.reconnectAttempts < this.maxReconnectAttempts) {
            this.reconnectAttempts++;
            this.log('WebSocket', `尝试重连... (${this.reconnectAttempts}/${this.maxReconnectAttempts})       ${this.url}`);
            setTimeout(() => {
                this.connect();
            }, this.reconnectInterval);
        } else {
            plus.runtime.restart();
            // this.closeHeartbeat();
            // this.log('WebSocket', `最大重连失败,终止重连: ${this.url}`);
        }
    }
 
    // >关闭连接
    close() {
        if (this.socket) {
            this.stopWs = true;
            this.socket.close();
            this.socket = null;
            this.removeEventListener('open');
            this.removeEventListener('message');
            this.removeEventListener('close');
            this.removeEventListener('error');
        }
        this.closeHeartbeat();
    }
 
    // >开始心跳检测 -> 定时发送心跳消息
    startHeartbeat() {        
        if (this.stopWs) return;
        if (this.heartbeatTimer) {
            this.closeHeartbeat();
        }
        this.heartbeatTimer = setInterval(() => {
            if (this.socket) {
                this.socket.send({
                    data: JSON.stringify({ type: 'heartBeat', data: {} }),
                    
                });
                this.log('WebSocket', '送心跳数据...');
            } else {
                console.error('[WebSocket] 未连接');
            }
        }, this.heartbeatInterval);
    }
 
    // >关闭心跳
    closeHeartbeat() {
        clearInterval(this.heartbeatTimer);
        this.heartbeatTimer = undefined;
    }
}