websocket使用包括重连心跳包
这种实现方案能够有效应对网络波动、服务器短暂不可用等情况,大幅提高 WebSocket 连接的稳定性。
·
class WebSocketClient {
constructor(url, options = {}) {
this.url = url;
this.ws = null; // WebSocket实例
this.isConnected = false; // 连接状态
this.reconnectTimer = null; // 重连定时器
this.heartbeatTimer = null; // 心跳定时器
this.reconnectCount = 0; // 重连次数
this.maxReconnectCount = options.maxReconnectCount || 10; // 最大重连次数
this.minReconnectInterval = options.minReconnectInterval || 1000; // 最小重连间隔(ms)
this.maxReconnectInterval = options.maxReconnectInterval || 30000; // 最大重连间隔(ms)
this.heartbeatInterval = options.heartbeatInterval || 30000; // 心跳间隔(ms)
this.heartbeatTimeout = options.heartbeatTimeout || 10000; // 心跳超时时间(ms)
this.heartbeatCheckTimer = null; // 心跳检测定时器
// 事件回调
this.onOpen = options.onOpen || (() => {});
this.onMessage = options.onMessage || (() => {});
this.onClose = options.onClose || (() => {});
this.onError = options.onError || (() => {});
this.onReconnect = options.onReconnect || (() => {});
// 初始化连接
this.connect();
}
/**
* 建立WebSocket连接
*/
connect() {
// 如果已经连接则关闭现有连接
if (this.ws) {
this.ws.close(1000, '手动重连');
}
try {
this.ws = new WebSocket(this.url);
// 连接成功回调
this.ws.onopen = (event) => {
this.isConnected = true;
this.reconnectCount = 0; // 重置重连次数
clearTimeout(this.reconnectTimer);
// 启动心跳
this.startHeartbeat();
// 触发打开事件
this.onOpen(event);
};
// 接收消息回调
this.ws.onmessage = (event) => {
// 如果是心跳响应,重置心跳检测
if (event.data === 'pong') {
this.resetHeartbeatCheck();
return;
}
// 触发消息事件
this.onMessage(event);
};
// 连接关闭回调
this.ws.onclose = (event) => {
this.isConnected = false;
clearTimeout(this.heartbeatTimer);
clearTimeout(this.heartbeatCheckTimer);
// 触发关闭事件
this.onClose(event);
// 如果不是正常关闭(1000),则尝试重连
if (event.code !== 1000) {
this.reconnect();
}
};
// 错误回调
this.ws.onerror = (error) => {
this.onError(error);
};
} catch (error) {
this.onError(error);
this.reconnect();
}
}
/**
* 发送消息
* @param {string|Object} data 要发送的数据
*/
send(data) {
if (!this.isConnected || !this.ws) {
console.error('WebSocket未连接,无法发送消息');
return false;
}
try {
const sendData = typeof data === 'object' ? JSON.stringify(data) : data;
this.ws.send(sendData);
return true;
} catch (error) {
console.error('发送消息失败:', error);
this.onError(error);
return false;
}
}
/**
* 启动心跳机制
*/
startHeartbeat() {
// 清除现有定时器
clearTimeout(this.heartbeatTimer);
clearTimeout(this.heartbeatCheckTimer);
// 定时发送心跳包
const sendHeartbeat = () => {
if (this.isConnected) {
this.send('ping');
// 启动心跳检测
this.startHeartbeatCheck();
}
this.heartbeatTimer = setTimeout(sendHeartbeat, this.heartbeatInterval);
};
// 立即发送第一个心跳
sendHeartbeat();
}
/**
* 启动心跳检测
*/
startHeartbeatCheck() {
clearTimeout(this.heartbeatCheckTimer);
this.heartbeatCheckTimer = setTimeout(() => {
// 心跳超时,关闭连接触发重连
console.warn('WebSocket心跳超时,准备重连');
this.ws.close(1006, '心跳超时');
}, this.heartbeatTimeout);
}
/**
* 重置心跳检测
*/
resetHeartbeatCheck() {
clearTimeout(this.heartbeatCheckTimer);
}
/**
* 重连机制
*/
reconnect() {
// 如果已达到最大重连次数,停止重连
if (this.reconnectCount >= this.maxReconnectCount) {
console.error(`已达到最大重连次数(${this.maxReconnectCount}),停止重连`);
return;
}
// 计算重连间隔(指数退避策略)
const exponent = Math.min(this.reconnectCount, 10); // 限制指数增长
const interval = Math.min(
this.minReconnectInterval * Math.pow(2, exponent),
this.maxReconnectInterval
);
// 延迟重连
this.reconnectTimer = setTimeout(() => {
this.reconnectCount++;
console.log(`正在进行第${this.reconnectCount}次重连...`);
this.onReconnect(this.reconnectCount, interval);
this.connect();
}, interval);
}
/**
* 手动关闭连接
*/
close() {
if (this.ws) {
this.ws.close(1000, '手动关闭');
}
clearTimeout(this.reconnectTimer);
clearTimeout(this.heartbeatTimer);
clearTimeout(this.heartbeatCheckTimer);
this.isConnected = false;
}
}
// 使用示例
// const wsClient = new WebSocketClient('wss://your-websocket-server.com', {
// maxReconnectCount: 15,
// heartbeatInterval: 20000,
// onOpen: (event) => {
// console.log('WebSocket连接成功');
// },
// onMessage: (event) => {
// console.log('收到消息:', event.data);
// },
// onClose: (event) => {
// console.log('WebSocket连接关闭:', event);
// },
// onError: (error) => {
// console.error('WebSocket错误:', error);
// },
// onReconnect: (count, interval) => {
// console.log(`准备进行第${count}次重连,间隔${interval}ms`);
// }
// });
//
// // 发送消息
// wsClient.send({ type: 'chat', content: 'Hello WebSocket' });
实现说明
这个 WebSocket 客户端工具类提供了完整的连接管理功能,主要特点包括:
-
核心功能:
- 基础的 WebSocket 连接建立与消息发送
- 自动重连机制(断开后自动尝试重新连接)
- 心跳检测(保持连接活跃,检测连接有效性)
-
重连策略:
- 采用指数退避算法,重连间隔逐渐增加(1s → 2s → 4s → ... 最大 30s)
- 可配置最大重连次数,避免无限重连
- 异常关闭时自动触发重连,正常关闭则不重连
-
心跳机制:
- 定期发送 "ping" 心跳包(默认 30 秒一次)
- 等待服务器返回 "pong" 响应(超时时间默认 10 秒)
- 心跳超时则判定连接失效,触发重连
-
事件回调:
- 提供 onOpen、onMessage、onClose、onError 等基础事件
- 增加 onReconnect 事件,方便跟踪重连状态
使用方法
- 实例化 WebSocketClient 并传入服务器地址和配置项
- 通过 onMessage 回调处理接收到的消息
- 使用 send 方法发送消息
- 必要时调用 close 方法手动关闭连接
注意事项
- 服务器端需要配合实现心跳响应(收到 "ping" 返回 "pong")
- 根据实际需求调整心跳间隔和超时时间
- 重连次数和间隔可根据网络环境灵活配置
- 生产环境中建议增加日志记录,方便排查连接问题
这种实现方案能够有效应对网络波动、服务器短暂不可用等情况,大幅提高 WebSocket 连接的稳定性。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)