websocket 链接时间长会自动断开(心跳机制)
websocket 链接时间长会自动断开(心跳机制)
WebSocket是一种全双工通信协议,允许服务器和客户端之间建立持久连接,这样双方可以随时发送数据。不过,有时候连接可能会因为网络问题或者服务器故障而中断,这时候就需要心跳机制来检测连接是否还存活。
在做的时候发现其实所谓的心跳机制就是客户端定时向服务器发送一个消息,服务器收到消息后返回一个确认消息,如果客户端在一段时间内没有收到服务器的确认消息,那么就认为连接已经断开,需要重新建立连接。
心跳机制的作用是检测连接是否还存活,如果连接断开,客户端可以及时知道,然后重新建立连接,避免因为连接断开而导致的数据丢失或者错误。
心跳机制的具体实现方式有很多种,比如定时发送一个空消息,或者发送一个包含时间戳的消息,服务器收到消息后返回一个包含时间戳的消息,客户端收到消息后更新时间戳,如果一段时间内没有收到服务器的消息,那么就认为连接已经断开。
我这里做的是客户端向后端发送一个包含信息类型的消息,后端向我返回一个包含信息类型的消息,我可以根据这个消息类型来判断是否走正常流程,还是走心跳机制的流程。
我这里的示例代码是uni-app中实现的websocket心跳机制,仅供参考:
let heartbeatInterval = ref(null)
let timeoutId = ref(null)
let socket = ref(null)
// 创建 WebSocket 连接
const websocketLink=()=>{
socket.value = uni.connectSocket({
url: `你的链接地址`,
method: "GET",
success: function (res) {
console.log("已经建立连接", res);
},
});
socket.value.onOpen(function (res : any) {
console.log("WebSocket连接已打开!", res);
// 打开链接,开启心跳机制
heartbeatHandle()
});
socket.value.onMessage(function (event : any) {
// 收到服务器内容
let msgData = JSON.parse(event.data);
if (data.f_mechanism == 'heartbeat_ack') {
// 清空定时器,说明连接正常
clearTimeout(timeoutId.value);
} else {
// 你的正常代码逻辑
}
});
socket.value.onClose(function (res : any) {
// 断开链接需要清空定时器
clearInterval(heartbeatInterval.value);
clearTimeout(timeoutId.value);
console.log("WebSocket连接已关闭!", res);
});
}
// 心跳机制
const heartbeatHandle = () => {
// 避免重复开启定时器
clearInterval(heartbeatInterval.value);
clearTimeout(timeoutId.value);
heartbeatInterval.value = setInterval(() => {
// 每隔 30 秒发送心跳包
let data = {
f_mechanism: 'heartbeat',
};
socket.value.send({
data: data
});
timeoutId.value = setTimeout(() => {
// 60 秒无响应则判定断开
// 将socket.value置为null,并重新连接
if (socket.value) {
socket.value.close();
}
socket.value = null;
websocketLink()
}, 60000);
}, 30000)
}
服务器端代码(Node.js):
wss.on('connection', (ws) => {
ws.on('message', (data) => {
const msg = JSON.parse(data);
if (msg.type === 'heartbeat') {
ws.send(JSON.stringify({ type: 'heartbeat_ack' }));
}
});
});
以上代码仅供参考
主要是注意定时器的使用,避免造成内存泄漏等问题