【问题标题】:Socket.IO emits multiple times in a room (Using with React.js)Socket.IO 在一个房间内多次发射(与 React.js 一起使用)
【发布时间】:2021-09-09 08:46:34
【问题描述】:

我有一个 react 应用程序,它允许多个用户加入一个房间,然后服务器随机选择一个用户,然后将所选用户的用户名发送给房间里的每个人。但问题是服务器多次发出同一个事件(发出的次数等于房间内的用户数)。

这是来自服务器的发出事件的代码:

socket.on("selectNextPlayer", roomid => {
        const selectedIndex = Math.round(Math.random()*rooms[roomid].participants.length);
        const selectedUsername = rooms[roomid].participants[selectedIndex];
        io.to(roomid).emit("setSelectedPlayer",selectedUsername); // THIS EVENT
        connectedUsers[selectedUsername].emit("myTurn");
    })

这是react客户端中监听事件的代码:

const socket = socketIOClient("http://127.0.0.1:8080");

useEffect(() => {
        if(isRoomOwner){
            socket.emit("createNewRoom", username,roomid);
        }else {
            socket.emit("joinNewRoom", username,roomid);
        }

        //Get all participants
        socket.on("allParticipants", (allparticipants, roomOwner) => {
            setParticipants(allparticipants);
            setOwner(roomOwner);
        })
        //Start/Stop Game
        socket.on("gameStatusChanged", gameStatus => {
            setGameStarted(gameStatus);
            //Select Next Player
            socket.emit("selectNextPlayer",roomid);
        })
        //set selected player
        socket.on("setSelectedPlayer", selectedPlayer => { //HERE
            setSelectedPlayer(selectedPlayer);
            setChats(prevChats => ([...prevChats,`Next player is ${selectedPlayer}`]))
        })
        //On my turn show truth/dare buttons
        socket.on("myTurn", () => {
            setIsMyTurn(true);
        })
    },[]);

问题是元素Next player is ${selectedPlayer}被多次添加到chats数组中,该数组存储在一个状态中。

我尝试将const socket = socketIOClient("http://127.0.0.1:8080"); 移动到另一个文件并使用import {socket} from '../services/socket'; 在顶部导入它,但没有成功。

编辑:(感谢@Tushar)

selectNextPlayer 被多次调用。

socket.on("gameStatusChanged", gameStatus => {
            setGameStarted(gameStatus);
            //Select Next Player
            socket.emit("selectNextPlayer",roomid);
        })

此函数调用发出 selectNextPlayer 函数。此函数监听 gameStatusChanged 事件并调用发出一个新的 selectNextPlayer 函数。

socket.on("startGame", roomid => {
        console.log("SELECT START GAME CALLED");
        io.to(roomid).emit("gameStatusChanged", true);
    })

此事件会发出 gameStatusChanged 事件,但它只被调用一次。那么为什么 selectNextPlayer 会被多次调用呢?

【问题讨论】:

  • gameStatusChanged 是如何调用的。检查它是否只被调用一次。您可以在 selectNextPlayer 上方添加一个控制台,以确认它被调用一次。
  • @TusharShahinOh yes selectNextPlayer 被多次调用
  • 这就是你想要的吗?因为那是触发错误发射的事件。
  • @TusharShahi 等一下让我更新问题
  • @TusharShahi 我编辑了问题,请立即检查

标签: javascript reactjs socket.io


【解决方案1】:

问题是

socket.on("gameStatusChanged", gameStatus => {
    setGameStarted(gameStatus);
    //Select Next Player
    socket.emit("selectNextPlayer",roomid);
})

在客户端,因此对于每个客户端,都会触发 "selectNextPlayer" 事件。因此,要将 socket.emit("selectNextPlayer",roomid); 这个移动修复到其他地方,对我来说,就是将它移动到发出 startGame 事件的同一个考试事件处理程序。

{
                username == owner && !gameStarted &&
                <button 
                    onClick={() => {
                        socket.emit("startGame",roomid);
                        socket.emit("selectNextPlayer", roomid);
                    }}
                >
                    Start Game
                </button>
            }

【讨论】:

    猜你喜欢
    • 2020-10-28
    • 2016-12-21
    • 2016-12-14
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 2013-08-01
    • 2018-05-07
    相关资源
    最近更新 更多