简体   繁体   中英

Socket.io response: How to get server to respond to multiple clients upon receiving info from all clients?

I'm learning about node.js, express, and socket.io

I've managed to successfully set up my server and connect to it from the browser using localhost:3000

I can send information from client to server and vice versa no problems.

What I now need to do is this.

Let's say we have 2 clients connected to the server.

Each client will send a piece of information.


socket.emit('mydata', datavariable);

On server:

socket.on('mydata', function(datavariable) {

         myArray.push(datavariable); //myArray declared globally

});

How do I code it so the server will do something like this.

if(myArray.length = #ofconnectedclients) {

  socket.emit("filledUpArray", myArray);

}

Or another way of saying it I guess is, once you have gotten a response from all clients connected, then do something.

I want to receive a piece of information from all clients, and after I have received that info from all clients, then send that data (now stored in an array) to all my clients.

Thanks!

So, it sounds like your problem statement is this:

When all connected clients have sent a certain piece of information to the server, then I want the server to do something.

First thing you have to do is keep track of all connected clients. You can either use socket.io's internal data structures for that or you can create your own. Here's creating your own on the server:

// map of all currently connected client objects
// socket is the key, custom object is the value
// methods are for managing data in the Map

let connectedSockets = new SocketMap();

// socket connects
io.on('connection', function(socket) {
    let socketData = {};
    socketData.socket = socket;
    socketData.dataReceived = false;
    // add it to our Map
    connectedSockets.set(socket, socketData);

    // monitor disconnects too
    socket.on('disconnect', function() {
        // remove it from the map
        connectedSockets.delete(socket);
    });
});

The second thing you need to do is to keep track of some per-socket state so you can initailize it at some point and then each time you receive a specific message from a client, you can check to see if all clients have sent the desired message. We'll create a couple functions to do that:

// this actually physically goes above the previous code, but I'm just placing it
// here for explanation purposes
class SocketMap extends Map {

    // clear the dataReceived Boolean to false for all sockets
    initReceived() {
        for (let [key, value] of this) {
            value.dataReceived = false;
        }
    }

    // return Boolean if all sockets have dataReceived set to true
    haveAllReceived() {
        for (let [key, value] of this) {
            if (!value.dataReceived) {
                return false;
            }
        }
        return true;
    }

    setReceived(socket) {
        let data = this.get(socket);
        if (!data) {
            return false;
        }
        data.dataReceived = true;
    }
}

Now you have methods on the connectedSockets Map object for keeping track of a dataReceived Boolean for each socket and for initializing them all to false and for setting one to true when a particular condition occurs (receiving a message) and for checking if they have all set the flag. So, you just have to determine when, in your code you want to call those messages.

Let's suppose that when the message you're waiting for from each socket is someMsg . So, you create a listener for that message and process it. We can incorporate that code into our previous connection handling code here:

// map of all currently connected client objects
// socket is the key, custom object is the value
// methods are for managing data in the Map

let connectedSockets = new SocketMap();

// socket connects
io.on('connection', function(socket) {
    let socketData = {};
    socketData.socket = socket;
    socketData.dataReceived = false;
    // add it to our Map
    connectedSockets.set(socket, socketData);

    // monitor disconnects too
    socket.on('disconnect', function() {
        // remove it from the map
        connectedSockets.delete(socket);
    });

    // process this message
    socket.on('someMsg', function(data) {
        connectedSockets.setReceived(socket);

        // if all sockets have now sent their data, then do something
        if (connectedSockets.haveAllReceived()) {
             // do your thing here

             // reset state, ready for next time
             connectedSockets.initReceived();
        }
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM