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

Socket.io无法向房间内所有用户推送事件?多人答题应用故障排查

多人答题应用启动游戏仅房主跳转问题排查

我们正在开发一款基于Socket.io和React的多人答题应用,目前创建房间与加入房间功能正常,但房主在大厅点击启动游戏后,只有房主自己跳转到答题页面,房间内其他用户没有任何响应。

相关代码

App.js

import io from "socket.io-client";
const URL = "http://localhost:3001"

const {
    difficulty,
    category,
    socket,
    setSocket,
    setAllPlayers,
    setUserData
} = useContext(QuizContext)

useEffect(() => {
    const newSocket = io(URL)
    newSocket.on("update_room", (users) => {
        setAllPlayers(users);
        setUserData(prev => {
            return {...prev, room: users[0]?.room}
        });
    }); 
}, [])

useEffect(() => {
    if(socket) {
        socket.on("game_started", () => {
            console.log(2);
            navigate("/quiz")
        });
    }
}, [socket]);

WaitingRoom.js

<button onClick={startQuiz}>Start</button>

const startQuiz = () => {
    socket.emit("start_quiz", { room: userData.room, data: userData.data });
};

后端socketEvents/index.js

socket.on("start_quiz", ({ room, data }) => {
    users = users.map((user) => {
        return { ...user, data };
    });
    io.to(room).emit("game_started", users);
});

问题修复方案

1. 存入Socket实例到Context

App.js中创建的newSocket没有通过setSocket存入Context,导致其他组件和监听game_started的useEffect拿到的socket是undefined,无法接收事件。修改第一个useEffect:

useEffect(() => {
    const newSocket = io(URL);
    // 将socket实例存入Context
    setSocket(newSocket);

    newSocket.on("update_room", (users) => {
        setAllPlayers(users);
        setUserData(prev => ({...prev, room: users[0]?.room}));
    }); 

    // 组件卸载时断开连接
    return () => newSocket.disconnect();
}, [setSocket, setAllPlayers, setUserData]);

2. 确保用户加入对应房间

检查用户加入房间的后端逻辑,必须调用socket.join(roomId)让用户进入指定房间,否则io.to(room).emit无法把事件发送给所有房间内用户。示例:

// 后端用户加入房间事件处理
socket.on("join_room", (roomId) => {
    socket.join(roomId);
    // 其他业务逻辑...
});

3. 优化game_started监听逻辑

避免重复监听事件,添加清理函数移除旧监听,同时确保依赖项完整:

useEffect(() => {
    if(!socket) return;

    const handleGameStart = () => {
        console.log(2);
        navigate("/quiz");
    };

    socket.on("game_started", handleGameStart);

    // 清理函数:移除监听
    return () => socket.off("game_started", handleGameStart);
}, [socket, navigate]);

4. 修复后端用户数据更新逻辑

后端当前会修改全局所有用户的data,应该只更新目标房间内的用户:

socket.on("start_quiz", ({ room, data }) => {
    users = users.map(user => 
        user.room === room ? {...user, data} : user
    );
    io.to(room).emit("game_started", users);
});

内容的提问来源于stack exchange,提问作者Brendan Joseph Geoghegan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:55:30