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

如何在socket.io聊天室中实现用户断开连接时的提示消息展示

Socket.io用户断开连接提示失效修复方案

问题根因

  • 依赖配置错误:负责注册socket事件的useEffect将chat加入了依赖数组,每次聊天记录更新都会重新执行该逻辑,导致socket反复重连、事件监听反复注册,第二个useEffect中存储的socket实例很快就会被替换为新实例,触发pre_disconnect时发送的事件无法被正确监听。
  • 缺少清理逻辑:注册socket事件的useEffect没有返回清理函数,旧的事件监听和socket连接不会被销毁,会出现大量重复监听、无效连接问题。
  • 主动上报方案不可靠:依赖客户端主动发送pre_disconnect的方案在用户直接关闭页面、网络异常断开时无法触发,提示会失效。

修复代码

服务端(Express/Node)

io.on('connection', socket => {
  // 存储当前socket对应用户名
  let currentUser = ''

  socket.on('message', ({ name, message }) => {
    io.emit('message', { name, message })
  })

  socket.on('join' , (name)=>{
    currentUser = name.usnm.toUpperCase()
    console.log(currentUser, 'joined')
    socket.broadcast.emit("join" , currentUser + " just joined")
  })

  // 直接监听socket自带的断开事件,不需要客户端主动上报
  socket.on('disconnect', () => {
    if (currentUser) {
      console.log(currentUser, 'left')
      socket.broadcast.emit("user_left", currentUser + " just left")
    }
  })
})

客户端(React.js)

const socketRef = useRef()
// 连接socket + 注册事件逻辑,无需添加chat依赖
useEffect(() => {
  socketRef.current = io.connect("http://localhost:4000")
  
  // 状态更新使用函数式写法,无需依赖外部chat变量
  socketRef.current.on("message", ({ name, message }) => {
    setChat(prev => [ ...prev, { name, message } ])
  })
  socketRef.current.on("join", (usnm) => {
    setChat(prev => [ ...prev, {name:usnm} ])
  })
  socketRef.current.on("user_left", (usnm) => {
    setChat(prev => [ ...prev, {name:usnm} ])
  })

  // 组件卸载时清理监听+断开连接
  return () => {
    socketRef.current.offAll()
    socketRef.current.disconnect()
  }
}, [])

// 上报用户加入逻辑
useEffect(() => {
  let usnm = sessionStorage.getItem("User");
  if (socketRef.current && usnm) {
    socketRef.current.emit("join" ,{usnm});
  }
}, [])

修复说明

  • 使用socket.io自带的disconnect事件处理断开逻辑,不管是客户端主动断开还是网络异常断开都能触发,可靠性更高。
  • 状态更新使用函数式写法,避免将chat加入useEffect依赖,防止socket反复重连。
  • 新增了socket事件和连接的清理逻辑,避免内存泄漏和重复监听问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 08:09:03