电脑之家
柔彩主题三 · 更轻盈的阅读体验

自动重连机制怎么写?手把手教你用 Python 和 JavaScript 实现

发布时间:2026-05-01 02:30:32 阅读:5 次

你有没有遇到过这样的情况:写了个监控程序,连着公司内网的 WebSocket 接口,结果中午断网五分钟,整个服务就卡死不动了?或者写的爬虫刚连上 API,对方服务器抖了一下,请求直接报错退出——根本没机会重试。

自动重连不是加个 while 就完事

很多人第一反应是写个死循环:while not connected: connect()。但这样容易把 CPU 跑满,还可能被目标服务限流甚至拉黑。真正的自动重连得考虑三件事:失败检测、退避策略、连接状态管理。

ref="/tag/136/" style="color:#3D6345;font-weight:bold;">Python 示例:带指数退避的 TCP 连接重试

假设你在写一个和 IoT 设备通信的客户端,用 socket 连接它的 TCP 端口:

import socket
import time
import random

def connect_with_retry(host, port, max_retries=5):
    for i in range(max_retries):
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(3)
            s.connect((host, port))
            print(f"✅ 第 {i+1} 次连接成功")
            return s
        except (socket.timeout, ConnectionRefusedError, OSError) as e:
            print(f"❌ 第 {i+1} 次连接失败:{e}")
            if i < max_retries - 1:
                # 指数退避 + 随机抖动,避免雪崩式重连
                delay = min(2 ** i + random.uniform(0, 1), 30)
                time.sleep(delay)
    raise Exception("重连全部失败,请检查网络或目标地址")

# 使用示例
try:
    sock = connect_with_retry("192.168.1.100", 8080)
    # 后续通信...
except Exception as e:
    print(e)

JavaScript(浏览器端)WebSocket 自动重连

网页里用 WebSocket 做实时聊天,一断网就白屏?试试这个轻量封装:

class ReconnectWebSocket {
  constructor(url, options = {}) {
    this.url = url;
    this.options = options;
    this.reconnectDelay = 1000; // 初始延迟 1s
    this.maxDelay = 30000;      // 最大延迟 30s
    this.ws = null;
    this.shouldReconnect = true;
    this.connect();
  }

  connect() {
    this.ws = new WebSocket(this.url);

    this.ws.onopen = () => {
      console.log("🟢 WebSocket 已连接");
      this.reconnectDelay = 1000; // 成功后重置延迟
    };

    this.ws.onclose = () => {
      if (this.shouldReconnect) {
        console.log(`🔴 连接关闭,${this.reconnectDelay}ms 后重试...`);
        setTimeout(() => this.connect(), this.reconnectDelay);
        this.reconnectDelay = Math.min(this.reconnectDelay * 1.5, this.maxDelay);
      }
    };

    this.ws.onerror = (err) => {
      console.error("⚠️ WebSocket 错误:", err);
    };
  }

  send(data) {
    if (this.ws?.readyState === WebSocket.OPEN) {
      this.ws.send(data);
    }
  }

  close() {
    this.shouldReconnect = false;
    this.ws?.close();
  }
}

// 使用
const ws = new ReconnectWebSocket("wss://api.example.com/chat");

关键细节别漏掉

心跳保活:长连接不发数据时,记得定时发 ping/ping 或空消息,不然中间防火墙/代理可能主动断开;
重复连接防护:重连逻辑里加个标志位,防止 onclose 触发多次 connect;
业务层兜底:比如重连期间用户发的消息,要缓存到队列,等恢复后再 flush;
日志分级:首次失败打 info,连续 3 次失败打 warning,5 次以上打 error,方便排查。

自动重连不是炫技,而是让程序在真实网络里活得更久一点。多试几次,把 delay 调成你家 Wi-Fi 断线再恢复的真实时间,比啥文档都管用。