Skip to content

Commit 014ea73

Browse files
committed
feat: Connection: keep-alive 传输层优化, heartbeat应用层长连接
1 parent 7eb1b8b commit 014ea73

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

network/heartbeat.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
class HeartbeatWebSocket {
2+
constructor(url) {
3+
this.url = url
4+
this.ws = null
5+
6+
this.heartbeatInterval = 5000 // 每5秒发一次心跳
7+
this.timeoutLimit = 15000 // 15秒没响应则断线
8+
9+
this.heartbeatTimer = null
10+
this.timeoutTimer = null
11+
12+
this.connect()
13+
}
14+
15+
connect() {
16+
console.log("正在连接")
17+
18+
this.ws = new WebSocket(this.url)
19+
20+
// 连接成功
21+
this.ws.onopen = () => {
22+
console.log("已连接")
23+
this.startHeartbeat()
24+
}
25+
26+
// 收到消息
27+
this.ws.onmessage = (event) => {
28+
if (event.data === "pong") {
29+
console.log("收到心跳")
30+
this.resetTimeout()
31+
} else {
32+
console.log("收到业务消息", event.data)
33+
}
34+
}
35+
36+
// 连接关闭
37+
this.ws.onclose = () => {
38+
console.log("连接关闭,准备重连...")
39+
this.reconnect()
40+
}
41+
42+
// 出错
43+
this.ws.onerror = (err) => {
44+
console.log("错误:", err)
45+
this.ws.close()
46+
}
47+
}
48+
49+
startHeartbeat() {
50+
// 定时发送 ping
51+
this.heartbeatTimer = setInterval(() => {
52+
if (this.ws.readyState === WebSocket.OPEN) {
53+
console.log("发送心跳")
54+
this.ws.send("ping")
55+
56+
// 启动超时检测
57+
this.resetTimeout()
58+
}
59+
}, this.heartbeatInterval)
60+
}
61+
62+
resetTimeout() {
63+
// 清除旧超时计时器
64+
if (this.timeoutTimer) {
65+
clearTimeout(this.timeoutTimer)
66+
}
67+
68+
// 超时未收到 pong
69+
this.timeoutTimer = setTimeout(() => {
70+
console.log("心跳超时,连接断开!")
71+
this.ws.close()
72+
}, this.timeoutLimit)
73+
}
74+
75+
reconnect() {
76+
// 清除心跳
77+
clearInterval(this.heartbeatTimer)
78+
clearTimeout(this.timeoutTimer)
79+
80+
// 延迟重连
81+
setTimeout(() => {
82+
this.connect()
83+
}, 3000)
84+
}
85+
}

0 commit comments

Comments
 (0)