0Pricing
React Academy · 课时

重连、错误处理与清理

妥善处理断开连接,并在 useEffect 中清理套接字监听器。

重连、错误处理与清理 是 CoddyKit 上的免费 React Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。

为什么重连很重要

移动设备上经常发生网络中断。如果没有重连逻辑,用户会在不知不觉中失去实时连接。好的策略是结合退避机制自动重试。

Socket.IO 自动重连

Socket.IO 默认会自动重连。请在 io() 选项中配置 reconnectionAttempts、reconnectionDelay 和 reconnectionDelayMax。

const socket = io('https://api.example.com', {
  reconnectionAttempts: 5,
  reconnectionDelay: 1000,       // initial delay
  reconnectionDelayMax: 10000,   // max delay (exponential backoff)
  randomizationFactor: 0.5,
});

在 React 中跟踪连接状态

监听 connect、disconnect 和 connect_error 事件,并将状态反映到组件状态中。

function useConnectionStatus() {
  const [status, setStatus] = useState<'connected' | 'disconnected' | 'error'>(
    socket.connected ? 'connected' : 'disconnected'
  );

  useEffect(() => {
    socket.on('connect', () => setStatus('connected'));
    socket.on('disconnect', () => setStatus('disconnected'));
    socket.on('connect_error', () => setStatus('error'));
    return () => {
      socket.off('connect');
      socket.off('disconnect');
      socket.off('connect_error');
    };
  }, []);

  return status;
}

显示重连提示条

套接字断开连接时显示提示条,让用户知道自己处于离线状态且正在重新连接。

function ConnectionBanner() {
  const status = useConnectionStatus();
  if (status === 'connected') return null;
  return (
    <div className="banner warning">
      {status === 'error' ? 'Connection failed' : 'Reconnecting...'}
    </div>
  );
}

手动重连

重试次数耗尽后,让用户通过按钮触发手动重连。

const [failed, setFailed] = useState(false);

socket.on('reconnect_failed', () => setFailed(true));

if (failed) {
  return (
    <button onClick={() => { setFailed(false); socket.connect(); }}>
      Retry connection
    </button>
  );
}

原生 WebSocket 重连

原生 WebSocket 没有内置重连功能。请手动实现指数退避:连接关闭后,等待 Math.min(delay * 2, maxDelay),再尝试建立新连接。

function connectWithBackoff(url, attempt = 0) {
  const ws = new WebSocket(url);
  ws.onclose = () => {
    const delay = Math.min(1000 * 2 ** attempt, 30000);
    setTimeout(() => connectWithBackoff(url, attempt + 1), delay);
  };
  return ws;
}

在 useEffect 中进行清理

在 useEffect 中添加的每个套接字监听器,都必须在清理函数中移除。未这样做会导致内存泄漏和重复的事件处理。

useEffect(() => {
  const onData = (d) => setState(d);
  socket.on('data', onData);

  return () => {
    socket.off('data', onData); // remove specific handler reference
  };
}, []);

避免处理程序中的陈旧闭包

当套接字处理程序引用状态或属性时,它会捕获陈旧闭包。请使用引用始终访问最新值。

const handlerRef = useRef(null);
handlerRef.current = (msg) => updateMessages(messages, msg); // fresh ref each render

useEffect(() => {
  const onMsg = (...args) => handlerRef.current(...args);
  socket.on('message', onMsg);
  return () => socket.off('message', onMsg);
}, []); // no deps needed

重连时发送待处理消息

断开连接时将传出消息加入 queue,并在连接重新建立后清空 queue。

const queue = useRef<string[]>([]);

socket.on('connect', () => {
  while (queue.current.length) {
    socket.emit('message', queue.current.shift());
  }
});

function send(text: string) {
  if (socket.connected) socket.emit('message', text);
  else queue.current.push(text);
}

重连后重新加入房间

Socket.IO 会在断开连接时清除房间成员关系。套接字重连后重新加入房间,以恢复订阅。

useEffect(() => {
  function rejoin() { socket.emit('join-room', roomId); }
  socket.on('connect', rejoin);
  return () => socket.off('connect', rejoin);
}, [roomId]);

全局错误处理

妥善处理无法恢复的错误:显示错误界面,并将重新加载页面作为最后的应对措施。

socket.on('connect_error', (err) => {
  console.error('Socket error:', err.message);
  // Show user-friendly error
});

快速检查

在 useEffect 清理过程中不移除套接字事件监听器,会有什么风险?

要点回顾

使用退避选项配置 Socket.IO 重连。在 React 状态中反映连接状态,显示重连提示条,重连后重新加入房间,并始终在 useEffect 清理过程中移除监听器。离线时将待处理消息加入队列,并在重连后发送。

常见问题解答

「重连、错误处理与清理」课时是免费的吗?

是的 — 「重连、错误处理与清理」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。

「重连、错误处理与清理」这节课中我会学到什么?

妥善处理断开连接,并在 useEffect 中清理套接字监听器。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 React Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「重连、错误处理与清理」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 React Academy 课中编写并运行代码吗?

能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 浏览器中的 WebSocket 基础
  2. 在 React 中使用 Socket.IO
  3. 构建实时聊天组件
  4. 重连、错误处理与清理
← 返回 React Academy