Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
351 views
in Technique[技术] by (71.8m points)

javascript - Socket.io - How to make the backend server wait until it has received an broadcast emit from all clients in a room

I'm creating a react application with socket.io. A part of the application includes a "question prompt" that is given to all the clients connected to the server. I'm having trouble with getting the backend server to continue operations only after it has received and answer from all of its clients. Here is the code below

SocketManager.js (aka Backend/Server)

const runGame = async (roomCode) => {

    // Variables for the game
    let prevAnswerSet = new Set();
    const delay = ms => new Promise(res => setTimeout(res, ms));
    const room = socketRooms.get(roomCode);
    const settings = room.getSettings();
    const players = room.generateImposters(settings.numImposters);
    const roomSocket = io.to(roomCode);
    
    // This socket emit event, sends all clients to an "intro" page for one second.
    roomSocket.emit(START_GAME, players, settings);
    console.log("START_GAME");
    await delay(1000);
    
    // This socket emit event, sends all clients to a NUMBER_TASK, where the users are asked to answer a question. 
    roomSocket.emit(SWITCH_SCREEN, NUMBERS_TASK, pickRandomQuestion(NumberPrompt));
    console.log('NUMBERS_TASK');
    await delay(10000);

    /*
    HELP NEEDED HERE
    Ideally I would like an asynchronus function where the server can emit a message to 
    all clients, receive the answer choices they made, and add them to the prevAnswerSet **defined above**
        
    await getAnswersFromClients() ;
    */

    // This socket emit event sends all clients to a VOTE_VIEW page where all the responses to the previous question are displayed. I will be passing in the answers from the previous questions in this emit event.

    roomSocket.emit(SWITCH_SCREEN, VOTE_VIEW /*,  [...prevAnswerSet.keys()]*/);
    console.log("VOTE_VIEW");
    await delay(10000);

    /*
        CONTINUE GAME PROCESS
    */
}

NumbersTask.js (Frontend React Component)

function NumbersTask(props) {
    const [answer, setAnswer] = useState(5);

    useEffect(() => {
        /*
            HELP NEEDED HERE
            Ideally looking for some socket event listener here that will send back to the server
            the answer for this specific client.
        */
    }, [answer]);

    let buttons = [];
    for(let i = 1; i <= 10; i++){
        const b = <button key={i} onClick={()=>setAnswer(i)}>{i}</button>
        buttons.push(b);
    }

    let prompt;
    if (props.currQuestion !== null){
        if(props.gameState.currPlayer.imposter) {
            prompt = 'You are the imposter, pick a number and DEFEND YOUR SELF'
        } else{
            prompt = props.currQuestion;
        }
    }
  

    return (
        <div>
            <h1>My response is {answer}</h1>
            <h2>{prompt}</h2>
            { buttons }
        </div>
    )
}

export default NumbersTask

All clients are sent to a NUMBER_TASK page where they will have to answer a question. After Waiting 10 seconds (from the await delay(10000)), I wish to emit an event to all clients connected to the Server and get all their answers (answered or unanswered is fine). I would imagine the socket listener would be placed inside the useEffect React Hook inside of NumberTask.js.

This issue would be trivial if it were an event sent from the server to one client. In this situation I would use an acknowledgement/callback function on the server. However, acknowledgement/callback functions are not allowed when the socket server broadcasts emit events to multiple clients.

So overall, I think there are two parts to this question

  1. How do I receive all the answers from the clients, if there are no callbacks allowed when broadcasting emits?
  2. How do I create an async function that will allow the server to wait until all the responses have been recorded before moving on to the next page!

Also on a smaller note, I have a feeling that coding my backend like this might not be a best practice or good design so please comment on that as well.

Thank you


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...