Socket.io的连接太多

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Socket.io的连接太多相关的知识,希望对你有一定的参考价值。

我在React、Node和Socket.io上做了一个聊天应用,每当我刷新页面或更换房间时,我都会有额外的连接。如何关闭之前的连接,如何管理它?我找到了socket.leave() nad socket.off(),但它对我不起作用。

服务器端

let listOfRooms = [];
var allClients = [];

mongoose
   .connect(
      `mongodb+srv://${process.env.DB_USER}:${process.env.DB_PASSWORD}@cluster0-lnoai.mongodb.net/${process.env.DB_NAME}?retryWrites=true&w=majority`
   )
   .then(() => {
      io.on('connection',(socket)=>{
         allClients.push(socket.id)
         console.log(allClients);

         socket.on('initRoom',({userData,roomList})=>{
            listOfRooms = roomList;

            listOfRooms.forEach(room=>{
            const nsp = io.of(room.id);
            nsp.on('connection', (nsSocket)=>{
                  nsSocket.on('joinRoom', ( data ) => {
                     const {userData, roomId} = data;
                     console.log(`joined to ${room.title}`);

                  });

                  nsSocket.on('sendMessage', (newMsg ) => {
                     const {roomId} = newMsg;
                  });
                  nsSocket.on('disconnect', () => {
                     console.log('disconnected nsSocket');

                     nsSocket.disconnect();
                     // removeUser(nsSocket.id)
                     // nsSocket.leaveAll(nsSocket.id);
                  })
               });
         })
      })
   })
})
.catch(err => {
   console.log(err);
});

客户端

useEffect(() => {
    socket = io(host);
    const roomList = [];
    namespaces.forEach((ns) => {
      ns.rooms.forEach((room) => {
        roomList.push(room);
      });
    });
    socket.emit('initRoom', { userData, roomList });
  }, []);

  useEffect(() => {
    const roomId = props.location.pathname.slice(1, props.location.pathname.length);
    roomSocket = io(`${host}${roomId}`);
    console.log(roomSocket);
    const data = {userData, roomId}
    roomSocket.emit('joinRoom', data);

    return () =>{
      roomSocket.emit('disconnect');

      roomSocket.off()
      socket.off()
    }
  }, [endpoint, props.location.pathname]);

  useEffect(() => {
    roomSocket.on('message', (message) => {
      console.log('tu patrz');
      const updatedMessages = [...messages, message];
      setMessages(updatedMessages);
    });

    roomSocket.on('roomData', ({ users }) => {
      setUsers(users);
      console.log('users:');
      console.log(users);
    });
  }, [messages, users]);

  const sendMessage = (newMsg) => {
    if (newMsg) {
      const roomId = props.location.pathname.slice(1, props.location.pathname.length);
      newMsg.roomId = roomId;

      roomSocket.emit('sendMessage', newMsg);
      setMessages('');
    }
  };

答案

试试 roomSocket.disonnect(true) 每当断开连接事件被触发时,都会被调用。

然而,如果你想强制每个客户端只有一个socket.io连接,那么你就必须实现某种认证系统,比如passport.js,然后使用cookie或token来唯一地识别用户。

由于一个socket id只能有一个连接,如果你将socket id设置为用户的token或session-id,那么你将有效地限制客户端每次只能有一个连接。

以上是关于Socket.io的连接太多的主要内容,如果未能解决你的问题,请参考以下文章

通过 c# 与 socket.io 服务器通信

断开连接时销毁socket.io连接

( Socket.io ) 一个socket连接多个房间

socket.io 连接事件不起作用,为啥?

仅当从 Node repl 运行代码时,Socket.IO 连接才有效

Socket.IO 中的跨域连接