Socket.IO 在一个房间内多次发射(与 React.js 一起使用)
Posted
技术标签:
【中文标题】Socket.IO 在一个房间内多次发射(与 React.js 一起使用)【英文标题】:Socket.IO emits multiple times in a room (Using with 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 我编辑了问题,请立即检查
【参考方案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>
【讨论】:
以上是关于Socket.IO 在一个房间内多次发射(与 React.js 一起使用)的主要内容,如果未能解决你的问题,请参考以下文章
在 NestJs 中使用 Socket IO 加入和发射到房间
Socket IO AngularJS(1.x) 工厂注入多次发射