Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Socket.io how to store more information that is common to room's users?

Tags:

socket.io

I'm developing a game using socket.io & nodejs. Two players get a set of boxes, which is an array, when they're done with what they had and I'm keeping record of how many set is requested.

The thing is I want to send request count to both players in the room whenever a request has been made. I can hold this info in database but that would be very inefficient, it's a real-time multiplayer game.

Because I have to emit both player's box count to the room, I thought having their box count in the room array would help but couldn't figure out. Just to give an idea:

In socket.io rooms hold info as this:

{ someUniqueSocketId : true, someAnotherSocketId : true}

I want it to hold like this:

{someUniqueSocketId : {setCountOfThisPlayer : true} ,
 someAnotherSocketId : {setCountOfThatPlayer : true}}

Or maybe there is a better way to hold such an info.

EDIT:

When a player sends a startGame signal, this works:

function startGame(){
    this.setCount = 0;
    io.to(matchRoom).emit('allSets', allSets);
};

allSets is an array of all boxes. It holds box count as property of the socket by this.setCount. But I cannot access other player's properties, so this doesn't work.

like image 858
muvaf Avatar asked Nov 27 '25 21:11

muvaf


2 Answers

Without storing it on the DB you could store it in a variable on the server. Not recommended becasue it eats mem and won't scale. Maybe you can tap into local storage of each user and manage it that way. It'd require a bit of coding but a few functions could handle that client side and you could have an additional function to update the server/players connected to the socket.

like image 68
Ravenous Avatar answered Dec 04 '25 13:12

Ravenous


You'll probably need to add a bit more structure to your server to track Players and Rooms outside of socket.io functionality.

Here's a quick example of how you might structure a simple room setup. I kept it quite simple and indulged in some structural shortcuts, so it probably wouldn't pass a best practices review.

var players = {};
var rooms = {};
rooms['randomId236512'] = {// add an example starter room
    id: 'randomId236512',
    name: 'Happy Box House Room',
    players: [],
    started: false,
    setCount: 0
};

function findOpenRoom() {
    //here you would search through the list of games waiting for players
    //if no rooms, make one, add it to the list, then return it
    return rooms[0];
}

io.on('connection', function (socket) {

var newPlayer = {//A better pratice would be create a "class" or new function for the Player object
    name: 'Mr. Jones',
    color: 'blue',
    currentRoom: null,
    requestedSets: [],//or could just be NumRequestedSets
    //Whatever additional game related data could go here
    //Alternately, if the data is specific to the whole game, put it on the room itself
};
players[socket.id] = newPlayer;//Adding this to the players dictionary will let us find the player object again via their socket id

var openRoom = findOpenRoom();
newPlayer.currentRoom = openRoom; //Now the player object has a reference to the game room it's in
openRoom.players.push(newPlayer);
socket.join(openRoom.id);//This will create a new socket.io channel to make it easy to emit to a single room

socket.on('startGame', function (socketId, msg) {
    var myRoom = players[socketId].currentRoom;
    myRoom.started = true;
    myRoom.setCount = 0;//Ensure 0 at start
    //Broadcast the startGame message here,  see below for building gamestate
});

socket.on('requestSet', function (socketId, msg) {

    sendSetOfBoxes(players[socketId]);//Respond to the message here, update the requested set number or whatever

    var gameState = {
        playerData: []
    };
    var myRoom = players[socketId].currentRoom;
    for (var i = 0; i < myRoom.players.length; i++) {
        //Loop over the players, and build a list of players and their history of requested sets
        gameState.playerData.push({
            name: myRoom.players[i].name,
            requestedSetHistory: myRoom.player[i].requestedSets
        })
    }
    socket.broadcast.to(myRoom.id).emit('setWasRequested', gameState);
});
function sendSetOfBoxes(player) {
    //do your sending of boxes here
}
});
like image 22
Kal_Torak Avatar answered Dec 04 '25 13:12

Kal_Torak



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!