WebSocket重连采用指数退避策略,即每次失败后延迟时间翻倍并加0–100ms随机抖动,上限设为30000ms,以避免冲击服务端并提升稳定性;可通过函数或ReliableWebSocket类实现,需注意防止重复连接、手动关闭状态管理及网络恢复检测等细节。

WebSocket 重连时用指数退避(Exponential Backoff)能有效避免频繁重连冲击服务端,同时提升客户端稳定性。核心是每次失败后延迟时间翻倍(带随机抖动),并设置上限防止等待过久。
基础指数退避逻辑
从初始延迟(如 1000ms)开始,每次重连失败就乘以一个增长因子(通常为 2),直到达到最大延迟(如 30000ms)。为避免多客户端同步重连,建议加入 0–100ms 的随机抖动。
- 第 1 次失败:延迟 ≈ 1000 + random(0–100) ms
- 第 2 次失败:延迟 ≈ 2000 + random(0–100) ms
- 第 3 次失败:延迟 ≈ 4000 + random(0–100) ms
- ……以此类推,上限设为 30000ms
在 reconnect 函数中实现
不依赖第三方库时,可封装一个带状态的重连函数,维护当前重试次数和延迟值:
Reconnecting in ${delay.toFixed(0)}ms...
更健壮的做法:封装成可复用类
把连接、重连、取消、重置等逻辑收拢,避免闭包变量污染和多次触发问题:
class ReliableWebSocket {
constructor(url, options = {}) {
this.url = url;
this.maxRetry = options.maxRetry ?? 10;
this.baseDelay = options.baseDelay ?? 1000;
this.maxDelay = options.maxDelay ?? 30000;
this.ws = null;
this.retryCount = 0;
this.isManuallyClosed = false;
}
<p>connect() {
this.ws = new WebSocket(this.url);</p><pre class="brush:php;toolbar:false;">this.ws.onopen = () => {
console.log('Connected');
this.retryCount = 0;
this.onopen?.();
};
this.ws.onclose = () => {
if (!this.isManuallyClosed && this.retryCount this.connect(), delay);
this.retryCount++;
}
};
this.ws.onerror = (err) => this.onerror?.(err);}
close() { this.isManuallyClosed = true; this.ws?.close(); }
reset() { this.close(); this.retryCount = 0; this.isManuallyClosed = false; } }
// 使用 const ws = new ReliableWebSocket('wss://api.example.com'); ws.onopen = () => console.log('Ready'); ws.connect();
注意事项与优化点
实际使用中还需考虑这些细节:
- 避免重复连接:在 onclose 触发重连前,检查 this.ws.readyState 是否为 0(CONNECTING)或未定义,防止重复 new WebSocket
- 手动关闭需清空状态:调用 close() 后应设 isManuallyClosed = true,并在重连前校验,否则用户主动断开后仍会自动重连
- 网络恢复检测:可监听 window.online/offline 事件,在网络恢复时提前触发重连(非必须,但体验更好)
- 日志与监控:记录重试次数、延迟值、最终是否成功,便于排查弱网或服务端问题
不复杂但容易忽略。关键不是“越快重连越好”,而是让失败后的等待变得聪明——有节制、有弹性、有边界。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











