You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Node+Socket.IO聊天应用卡死,报connection failed:insufficient resources错误

错误原因与解决方案

错误根源

  • 重复创建Socket连接:Chat组件每次重新渲染时,组件顶层的socket = io(ENDPOINT)都会执行一次创建新连接,同时第一个useEffect依赖name和room,每次状态更新又会再创建一次连接,旧连接未主动关闭,短时间内产生大量TCP连接耗尽设备网络资源,触发资源不足报错。
  • 事件监听泄漏:第二个useEffect依赖joined数组,每次joined更新都会新增一个userName事件监听,旧监听未被移除,导致回调重复执行、内存占用持续升高,进一步加剧资源消耗。
  • 无连接释放逻辑:组件卸载时没有主动断开Socket连接,连接持续占用资源得不到释放。

修复方案

直接替换原有Chat组件的逻辑即可:

import React from "react";
import SendIcon from "@material-ui/icons/Send";
import "./chat.css";
import { useEffect, useState } from "react";
import { useLocation } from "react-router-dom";
import chat from "./chat.svg";
import TextField from "@material-ui/core/TextField";
import AccountCircleSharpIcon from "@material-ui/icons/AccountCircleSharp";
import FingerprintSharpIcon from "@material-ui/icons/FingerprintSharp";
import io from "socket.io-client";

function Chat() {
  let [name, setName] = useState();
  let [room, setRoom] = useState();
  let [childWidth, setChildWidth] = useState({ width: "50vw" });
  let [btnColor, setBtnColor] = useState({ fontSize: "4vmax" });
  let [joined, setJoined] = useState([]);

  const ENDPOINT = "http://localhost:5000";
  const search = useLocation().search;

  useEffect(() => {
    const name1 = new URLSearchParams(search).get("name");
    const room1 = new URLSearchParams(search).get("id");
    setName(name1);
    setRoom(room1);

    if (window.innerWidth <= 1080) {
      setChildWidth({ width: "100%", height: "100%" });
      setBtnColor({ fontSize: "6vmax" });
    }

    // 仅在组件挂载/路由参数变化时创建一次socket实例
    const socket = io(ENDPOINT);
    socket.emit("userName", { name1, room1 });

    // 绑定事件监听,使用函数式更新避免依赖joined数组
    const handleUserJoin = (payload) => {
      setJoined(prev => [...prev, payload.name1]);
    };
    socket.on("userName", handleUserJoin);

    // 清理逻辑:移除监听、断开连接释放资源
    return () => {
      socket.off("userName", handleUserJoin);
      socket.disconnect();
    };
  }, [search]);

  return (
    <>
      <main id="main_chat">
        <section id="child_child" style={childWidth}>
          <header id="header_child">
            <div id="username_roomid">
              <p id="user_name">
                <span id="user_logo">
                  {" "}
                  <AccountCircleSharpIcon />
                </span>{" "}
                <span id="name_of_user">{name}</span>
              </p>
              <p id="room_name">
                <span id="room_logo">
                  <FingerprintSharpIcon />
                </span>{" "}
                <span id="id_of_room">{room}</span>
              </p>
            </div>

            <div id="logo_name">
              <img src={chat} alt="聊天logo" />
              <h2>R Chat</h2>
            </div>
          </header>
          <section id="msg_area">
            {joined.map((value, index) => {
              return <p key={index}>{value} has joined</p>;
            })}
          </section>

          <footer id="footer_child">
            <div id="footer_input_child">
              <TextField
                id="msg_input"
                label="Enter a message"
                variant="outlined"
                fullWidth
              />
            </div>

            <div id="footer_button_child">
              <SendIcon id="send_button" style={btnColor} />
            </div>
          </footer>
        </section>
      </main>
    </>
  );
}

export default Chat;

改动说明

  • 移除了组件顶层和冗余的Socket实例创建逻辑,仅在路由参数变化时创建一次连接
  • 使用state函数式更新,消除了对joined数组的依赖,避免重复创建事件监听
  • 新增组件卸载时的清理逻辑,主动移除事件监听、断开Socket连接释放资源
  • 补充了列表渲染的key属性和img标签的alt属性,修复React原生警告

内容的提问来源于stack exchange,提问作者Rohit Sahu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 15:24:02