0

I am writing the server code for a small game, and after several tests I am getting this error Maximum call stack size exceeded.

The logic is really simple. Each instance of the game needs 2 players. When a player visits the localhost server he is presented with 2 choices: host and join. In the server-side code there's a javascript object which keeps track of the games that are available. When a user selects join, the server emits the data inside the object and each available game is presented to the user in the form of a button.

The structure of the object is the following (for 2 games running):

var games = {
    game_IDs : [],
    socketIDOfHost1: {
        "player1": socketOfPlayer1,
        "player2": socketOfPlayer2
    },
    socketIDOfHost2: {
        "player1": socketOfPlayer1,
        "player2": socketOfPlayer2
    }
}

The code is this:

Server:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
    res.sendFile(__dirname + '/index.html');
});

var games = {
    game_IDs: []
};

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

    socket.on('join', function (data) {
        socket.emit('join-data', games);
    });

    socket.on('host', function () {
        games.game_IDs.push(socket.id);
        games[socket.id] = {};
        games[socket.id]["player1"] = socket.id;
        socket.emit('host-data', socket.id);
    });

    socket.on('game-select', function (data) {
        games[data]["player2"] = socket;
        games[socket.id]  = games[data];
    });

});

http.listen(4000, function () {
});

Client:

    var socket = io();
    function host() {
        document.getElementById("container").style.visibility = "visible";
        socket.emit('host', socket.id);
    }

    function join(){
        document.getElementById("container").style.visibility = "visible";
        socket.emit('join', "kappapride");
    }

    function selectGame(id) {
        socket.emit('game-select', id);
    }

    socket.on('host-data', function (data) {
        let e = document.getElementById("container");
        let p1 = document.createElement("div");
        p1.innerHTML = "<h1>Player1: " + data + "</h1>";
        p1.style.width = "100%";
        e.appendChild(p1);
    });

    socket.on('join-data', function (data) {
        let e = document.getElementById("container");
        for(let i=0; i<data.game_IDs.length; i++){
            let game = document.createElement("button");
            game.innerHTML = data.game_IDs[i];
            game.addEventListener("click", function () {
                selectGame(this.innerHTML);
            });
            game.style.position = "absolute";
            game.style.width = "100%";
            game.style.height = "50px";
            game.style.backgroundColor = i%2==0? "aqua": "aliceblue";
            e.appendChild(game);
        }
    });

If I open 2 instances of the browser, host with one of them, and join with the other, everything works as expected, the game is found and displayed as a button. If i open 3 instances, host with two of them, and join with the last, I get this error.

It's clearly a memory issue, but the plan is to have it work, with possibly more than 2 instances of the game running simoultaneously. Is there a something I can do? Am I looking at this the wrong way?

VlassisFo
  • 650
  • 1
  • 8
  • 26
  • Where are you getting that error, on the server, the first client or the second client? – Bergi Oct 12 '17 at 20:53
  • Are you getting the `RangeError: maximum call stack size exceeded` – kemotoe Oct 12 '17 at 20:55
  • @kemotoe Yes exactly – VlassisFo Oct 12 '17 at 20:57
  • @Bergi The third client. The first two host a game and the third tries to join. When the join button is pressed this error is thrown. – VlassisFo Oct 12 '17 at 20:57
  • So `host` and `join` are button press handlers? You might want to post that code (and minimal html markup) as well – Bergi Oct 12 '17 at 21:01
  • Do you get any stack trace with the exception? You should be able to use devtools to see which functions are involved in the recursion – Bergi Oct 12 '17 at 21:02
  • `games[data]["player2"] = socket;` and `games[socket.id] = games[data];` seems like a self-reference especially since you are emitting `games` later. – holmberd Oct 12 '17 at 21:06
  • @holmberd actually it's there for that reason. It's important that i can access the same game through both the socket-ids of the 2 players – VlassisFo Oct 12 '17 at 21:08
  • @Bergi host and join are button handlers, also i am not sure how to use the devtools... Could you point something out for me? – VlassisFo Oct 12 '17 at 21:09
  • @Alan https://developers.google.com/web/tools/chrome-devtools/javascript/breakpoints#exceptions (although you might want to read the whole documentation) – Bergi Oct 12 '17 at 21:12

0 Answers0