useEffect 无法与我的组件内的 socket.on 一起使用

发布于 2025-01-10 06:55:45 字数 2502 浏览 0 评论 0原文

我目前正在尝试接收组件 ListeRoom 中的所有活动房间。我的 useEffect 似乎不起作用,因为我目前在客户端没有收到任何信息。在服务器端,我可以看到所有活动房间的列表都是通过 getActiveRooms() 的 console.log 返回的。我做错了什么吗?

服务器端

const express = require('express');
const app = express();
const http = require('http');
const cors = require('cors'); 
const { Server } = require("socket.io");
app.use(cors());

const PORT = 3001;
const server = http.createServer(app);

const io = new Server(server, { 
    cors: {
        origin: 'http://localhost:3000',
        methods: ["GET", "POST"],
    }
});

function getActiveRooms(io) {
    // Convert map into 2D list:
    // ==> [['4ziBKG9XFS06NdtVAAAH', Set(1)], ['room1', Set(2)], ...]
    const arr = Array.from(io.sockets.adapter.rooms);
    // Filter rooms whose name exist in set:
    // ==> [['room1', Set(2)], ['room2', Set(2)]]
    const filtered = arr.filter(room => !room[1].has(room[0]))
    // Return only the room name: 
    // ==> ['room1', 'room2']
    const res = filtered.map(i => i[0]);
    console.log(`Liste des rooms actives : ${res}`)
    return res;
}

io.on("connection", (socket) => {
    socket.on("room_list", (data) => {
        socket.join(data); //data is a room called listroom that will receive all rooms (string)
        socket.to(data).emit("receive_room", getActiveRooms(io)); 
    });
});

server.listen(PORT, () => {
    console.log(`Serveur lancé sur le port ${PORT}`);
});

客户端(它是一个名为 ListeRoom 的组件)

function ListeRooms({socket, username}) {

    const PORT = 3001;
    const socket = io.connect(`http://localhost:${PORT}`); //Pour connecter le frontend au backend

    const classes = useStyles(); 
    const [roomList, setRoomList] = useState([]);
    
    useEffect(() => {
        socket.on("receive_room", (data) => {
            console.log('Data fetched',data)
            setWebData(data);
        });
        socket.on("connect_error", () => {
          console.error("socket error!");
        socket.close();
      });
       // remove the socket listener when component left!
       return () => {
       socket.close();
      }
    }, []);
    // second use effect if web data changed!
    useEffect(() => {
      if(webData){
        // if webData is array of objects
        setRoomList([...roomList, ...webData]);
        //if webData is just objects
         setRoomList([...roomList, webData]);
        //refresh the local state
         setWebData([]);
       }
    },[webData])

I am currently trying to receive all active room in my component ListeRoom. My useEffect don't seem to work because I am currently receiving no information on the client side. On the server side I can see that the list of all active room as been returned with my console.log from getActiveRooms(). Am I doing something wrong ?

Server Side

const express = require('express');
const app = express();
const http = require('http');
const cors = require('cors'); 
const { Server } = require("socket.io");
app.use(cors());

const PORT = 3001;
const server = http.createServer(app);

const io = new Server(server, { 
    cors: {
        origin: 'http://localhost:3000',
        methods: ["GET", "POST"],
    }
});

function getActiveRooms(io) {
    // Convert map into 2D list:
    // ==> [['4ziBKG9XFS06NdtVAAAH', Set(1)], ['room1', Set(2)], ...]
    const arr = Array.from(io.sockets.adapter.rooms);
    // Filter rooms whose name exist in set:
    // ==> [['room1', Set(2)], ['room2', Set(2)]]
    const filtered = arr.filter(room => !room[1].has(room[0]))
    // Return only the room name: 
    // ==> ['room1', 'room2']
    const res = filtered.map(i => i[0]);
    console.log(`Liste des rooms actives : ${res}`)
    return res;
}

io.on("connection", (socket) => {
    socket.on("room_list", (data) => {
        socket.join(data); //data is a room called listroom that will receive all rooms (string)
        socket.to(data).emit("receive_room", getActiveRooms(io)); 
    });
});

server.listen(PORT, () => {
    console.log(`Serveur lancé sur le port ${PORT}`);
});

Client Side (it's a component called ListeRoom)

function ListeRooms({socket, username}) {

    const PORT = 3001;
    const socket = io.connect(`http://localhost:${PORT}`); //Pour connecter le frontend au backend

    const classes = useStyles(); 
    const [roomList, setRoomList] = useState([]);
    
    useEffect(() => {
        socket.on("receive_room", (data) => {
            console.log('Data fetched',data)
            setWebData(data);
        });
        socket.on("connect_error", () => {
          console.error("socket error!");
        socket.close();
      });
       // remove the socket listener when component left!
       return () => {
       socket.close();
      }
    }, []);
    // second use effect if web data changed!
    useEffect(() => {
      if(webData){
        // if webData is array of objects
        setRoomList([...roomList, ...webData]);
        //if webData is just objects
         setRoomList([...roomList, webData]);
        //refresh the local state
         setWebData([]);
       }
    },[webData])

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

隔纱相望 2025-01-17 06:55:45

在客户端,即使您从服务器收到响应,它也不会更新您应该使用 2 个 useEffects 函数的状态:类似这样。

// new file.js
import io from "socket.io-client";
export const socket = io(process.env.API_URL || 'http://localhost:3000');

// component.jsx
function ListeRooms({username}) {
import socket from 'path/to/newfile'
const classes = useStyles(); 
const [roomList, setRoomList] = useState([]);
const [webData , setWebData] = useState([]);

useEffect(() => {
    socket.on("receive_room", (data) => {
        console.log('Data fetched',data)
        setWebData(data);
    });
    socket.on("connect_error", () => {
      console.error("socket error!");
    socket.close();
  });
   // remove the socket listener when component left!
   return () => {
   socket.close();
  }
}, []);
// second use effect if web data changed!
useEffect(() => {
  if(webData){
    // if webData is array of objects
    setRoomList([...roomList, ...webData]);
    //if webData is just objects
     setRoomList([...roomList, webData]);
    //refresh the local state
     setWebData([]);
   }
},[webData])

In the client-side even if you get a response from the server it will not update the state you should use 2 useEffects functions: something like this.

// new file.js
import io from "socket.io-client";
export const socket = io(process.env.API_URL || 'http://localhost:3000');

// component.jsx
function ListeRooms({username}) {
import socket from 'path/to/newfile'
const classes = useStyles(); 
const [roomList, setRoomList] = useState([]);
const [webData , setWebData] = useState([]);

useEffect(() => {
    socket.on("receive_room", (data) => {
        console.log('Data fetched',data)
        setWebData(data);
    });
    socket.on("connect_error", () => {
      console.error("socket error!");
    socket.close();
  });
   // remove the socket listener when component left!
   return () => {
   socket.close();
  }
}, []);
// second use effect if web data changed!
useEffect(() => {
  if(webData){
    // if webData is array of objects
    setRoomList([...roomList, ...webData]);
    //if webData is just objects
     setRoomList([...roomList, webData]);
    //refresh the local state
     setWebData([]);
   }
},[webData])
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文