Node.js + Socket.io Maximum Call Stack Size

For my Node application, I have a server (app.js) running on Debian serving both html and websocket data using socket.io for my client (index.html). I am trying to make a turn-based multiplayer HTML5 game.

After making several successful data transfers using socket.emit () / io.emit () and socket.on () my server crashes to socket.emit () with an error
"events.js: 72
throw er; // Unhandled event 'error'
RangeError: Maximum call stack size exceeded. "
I have quite a few socket.on () event listeners, each of which processes a different function in the game (e.g. roll_dice, end_turn, ready_to_play, etc.).

I tried to investigate the problem (found a lot of discussion in asynchronous loops), but could not find how to apply the solutions to my own code. I have attached the appropriate source here. You can also view the entire source in my github at: https://github.com/sjmoon0/gameofdeath

index.html

var socket = io.connect('http://131.178.15.173',{'forceNew':true}); ... //----------------Initialization and Menu functions----------- socket.on('load', function (data) { console.log(data); clientID=data; socket.emit('check_game_started', { un: clientID }); socket.on('last_client_loaded', function(hasStarted){ console.log("Has game started? :"+hasStarted); if(hasStarted==true){ $('#choosecharacter').show(); } }); }); socket.on('client_disconnect', function (data) { console.log(data); }); socket.on('client_counter', function (data) { if(data<5){ console.log(data); incrementLoadBar(data); allowedInGame=true; } if(!allowedInGame){ ... } }); socket.on('game_started', function (data) { console.log(data); $('#welcome').hide(); $('#choosecharacter').show(); }); socket.on('set_user', function(characterName){ chosenCharacter=characterName; }); socket.on('disable_player_choice', function(data){ var id=data.stuff[0].chara; incrementLoadBar(data.stuff[0].numChar); console.log(id +" was chosen"); $('#'+id).hide(); }); //-------------------Gameplay functions socket.on('start_gameplay',function(nonsense){ showChanges(nonsense); $('#wait').hide(); $('#gamespace').show(); draw_c(); socket.emit('ready_to_play',chosenCharacter); }); socket.on('take_turn',function(updatedBoard){ showChanges(updatedBoard); if(updatedBoard.currPlayer==chosenCharacter){ promptUser(updatedBoard); } }); socket.on('roll_result',function(rollResult){ promptUser(rollResult); }); ... $('#rollDiceButton').click(function(){ socket.emit('roll_dice',chosenCharacter); }); $('#okCloseButton').click(function(){ socket.emit('end_turn',chosenCharacter); }); $('.thumbnail').click(function(something){ socket.emit('player_chosen', something.target.id); ... }); 

app.js

 var app = require('http').createServer(handler) var io = require('socket.io')(app); var fs = require('fs'); var url = require('url'); ... app.listen(8001); function handler (req, res) { ... } console.log("~Server Running~"); io.on('connection', function (socket) { console.log("A Client connected"); ... socket.emit('load', { user: uID }); io.emit('client_counter',numClients); if(numClients==4){ gameStarted=true; console.log("Game started!"); io.emit('game_started',"The Game has begun!"); } else if(numClients>4){ numClients--; delete allClients[allClients.indexOf(socket)]; } socket.on('check_game_started', function (data) { socket.emit('last_client_loaded', gameStarted); console.log(data); if(gameStarted){ console.log("Last Player Loaded!"); } }); socket.on('player_chosen', function(cp){ ... socket.emit('set_user', cp); ... io.emit('disable_player_choice',{'stuff':[{'chara':cp,'numChar':numCharChosen}]}); if(numCharChosen==4){ io.emit('start_gameplay', boardUpdate); } }); socket.on('disconnect',function(){ console.log("A client disconnected"); numClients--; delete allClients[allClients.indexOf(socket)]; io.emit('client_disconnect',"We've lost another comrade!"); }); socket.on('ready_to_play',function(characterThatIsReadyToPlay){ io.emit('take_turn',boardUpdate); }); socket.on('roll_dice', function(characterThatRolledDice){ var temp=generateRollResult(characterThatRolledDice) socket.emit('roll_result',temp); }); socket.on('end_turn',function(characterThatEndedTurn){ io.emit('take_turn',nextUpdate(characterThatEndedTurn)); }); }); 

Please be careful, I just started using Node.js about a week ago. Thanks!

+10
source share
7 answers

Found my problem.

The object (temp) that I tried to send over the network (to socket.emit ('roll_result', temp);) was an array of self-references. This was a recursive property of the array, which caused the stack to exceed the maximum size.

+43
source

The answer is very helpful. Thanks.

I had the same problem, and I want to share with someone who might run into it.

My code uses express.js and has the following:

 io = require('socket.io').listen(server); ...... io.to(socketId).emit('hello', {userId:userId, data:data, res:res}); 

He generated the error "Maximum call stack exceeded." The problem is that I should not send the res variable to the client on the socket. I guess this will lead to some recursive behavior if I do this.

The solution simply removes the 'res' from the emit statement:

 io.to(socketId).emit('hello', {userId:userId, data:data}); 
+6
source

This is the same error that I encountered when I clicked the submit button. He disconnected and selected "Maximum call stack size." I restarted my browser, it worked .. Strange behavior

0
source

I would like to share my mistake on the same issue:

  public createClient() { this.client = new net.Socket(); this.client.connect(this.port, this.ip, () => { this.emit("connect"); }); this.client.on("data", (data) => { this.emit("data", data); }); this.client.on("close",function () => { this.emit("close"); }); } 

in the close event, using a normal function, and this (the cause of the error) leads to the closing cycle of the close event, resulting in a stack size error.

  this.client.on("close", () => { this.emit("close"); }); 

Using arrow func. (or by copying real this into something like _this and using the inside function) the problem is solved.

It is actually unaware of the context of the function (in the callback) or negligence ..

0
source

wow, just ran into this problem today! If I had not found this post, another year could have passed. lol

0
source

I had the same problem. For me, the problem was that the object that I emitted in the socket contained a link to the socket itself. So I basically sent the socket inside the socket. Do not try to do it at home :)

0
source

I had the same problem, it happened because I was sending 3 objects with emit, I solved it by sending only one object

0
source

Source: https://habr.com/ru/post/1208646/


All Articles