WebSocketManager 组件介绍
WebSocketManager 是一个用于管理 WebSocket 连接的封装组件,旨在简化 WebSocket 的使用,提供连接管理、消息发送、断线重连、心跳机制等功能。通过该组件,开发者可以快速实现 WebSocket 通信,并处理常见的连接问题。
主要功能
连接管理:
支持创建 WebSocket 连接,并自动处理连接成功、失败和关闭事件。
提供手动关闭连接的方法,确保资源释放。
断线重连:
当连接意外断开时,自动尝试重连,支持设置最大重连次数和重连间隔。
避免因网络波动导致的连接中断问题。
心跳机制:
支持定时发送心跳消息,保持连接活跃,防止因长时间无通信而被服务器断开。
消息发送与接收:
提供 sendMessage 方法,确保在连接打开时发送消息。
支持自定义消息接收回调函数,方便处理服务器返回的数据。
错误处理:
捕获并记录 WebSocket 错误事件,便于排查问题。
使用场景
实时通信应用(如聊天室、在线协作工具)。
实时数据监控(如设备状态、报警信息推送)。
需要保持长连接的场景(如在线游戏、实时通知)。
- 调用案例如下:
const socketManager = new WebSocketManager(‘ws://example.com/socket’, receiveMessage)
socketManager.start()
.then(() => { })
.catch(error => { })
})
export default class WebSocketManager {
constructor(url = null, msg, receiveMessageCallback = null) {
this.socket = null // WebSocket 对象
this.pingTimeout = null // 心跳计时器
this.reconnectTimeout = null // 重连计时器
this.reconnectTime = 3000 // 重连间隔,单位:毫秒
this.maxReconnectAttempts = 3 // 最大重连尝试次数
this.reconnectAttempts = 0; // 当前重连尝试次数
this.url = url // WebSocket 连接地址
this.msg = msg // 发送的消息
this.receiveMessageCallback = receiveMessageCallback // 接收消息回调函数
this.isManualClose = false // 标记是否手动关闭连接
this.messageQueue = []; // 消息队列,用于存储连接未打开时的消息
}
/**
* 启动 WebSocket 连接
* @returns {Promise<void>}
*/
start() {
return new Promise((resolve, reject) => {
if (this.url) {
this.isManualClose = false;
this.connectWebSocket(resolve, reject);
} else {
reject(new Error('WebSocketManager erros: 请传入连接地址'));
}
});
}
/**
* 创建 WebSocket 连接
* @param {Function} resolve Promise 的 resolve 回调
* @param {Function} reject Promise 的 reject 回调
*/
connectWebSocket(resolve, reject) {
// 创建 WebSocket 对象
this.socket = new WebSocket(this.url);
// 处理连接打开事件
this.socket.onopen = () => {
console.log('连接成功');
resolve(); // 连接成功,触发 Promise 的 resolve
// 发送初始消息
this.sendMessage(this.msg);
// 发送队列中的消息
this.messageQueue.forEach(message => this.sendMessage(message));
this.messageQueue = []; // 清空队列
// 启动心跳机制
// this.startHeartbeat();
};
// 处理接收到消息事件
this.socket.addEventListener('message', event => {
this.receiveMessage(event)
})
// 处理连接关闭事件
this.socket.onclose = event => {
console.log('断线重连中·····', event);
// 如果是手动关闭,则不重连
if (this.isManualClose) {
console.log('手动关闭连接,不重连');
return;
}
// 清除定时器
clearTimeout(this.pingTimeout)
clearTimeout(this.reconnectTimeout)
// 尝试重连
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++
this.reconnectTimeout = setTimeout(() => {
this.connectWebSocket()
}, this.reconnectTime)
} else {
// 重置重连次数
this.closeWebSocket()
console.error('已达到最大重新连接尝试次数。无法重新连接。')
}
}
// 处理连接错误事件
this.socket.onerror = (event) => {
console.error('WebSocketManager error:', event);
reject(event); // 连接失败,触发 Promise 的 reject
};
}
/**
* 启动心跳机制
*/
startHeartbeat() {
this.pingTimeout = setInterval(() => {
// 发送心跳消息
this.sendMessage('ping')
}, 10000) // 每隔 10 秒发送一次心跳
}
/**
* 发送消息
* @param {String} message 消息内容
*/
sendMessage(message) {
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
this.socket.send(message);
} else {
console.warn('WebSocket 连接未打开,消息加入队列');
this.messageQueue.push(message); // 将消息加入队列
}
}
/**
* 接收到消息
*/
receiveMessage(event) {
// 根据业务自行处理
// 传入回调函数自行处理
this.receiveMessageCallback && this.receiveMessageCallback(event.data) // 修复
}
/**
* 关闭连接
*/
closeWebSocket() {
this.isManualClose = true // 标记为手动关闭
this.socket.close()
// 清除定时器 重置重连次数
clearTimeout(this.pingTimeout)
clearTimeout(this.reconnectTimeout)
this.reconnectAttempts = 0
}
}