2014-12-09 14 views
5

Per l'applicazione Node, ho un server (app.js) in esecuzione su Debian che serve sia dati html che websocket utilizzando socket.io al mio client (index.html) . Sto tentando di creare un gioco multiplayer HTML5 a turni.Node.js + Socket.io Numero massimo di stack di chiamate superato

Dopo l'esecuzione di una serie di trasmissioni di dati di successo usando socket.emit()/io.emit() e socket.on(), i miei server si blocca su un socket.emit() chiamata con l'errore
"eventi. js: 72
throw er; // evento 'error' non gestito
RangeError: superata la dimensione massima dello stack di chiamate ".
Ho un discreto numero di ascoltatori di eventi socket.on(), ognuno dei quali gestisce una funzione diversa nel gioco (ad esempio roll_dice, end_turn, ready_to_play, ecc.).

Ho tentato di ricercare il problema (ho trovato molte discussioni sui cicli asincroni), ma non sono riuscito a trovare come applicare le soluzioni al mio codice. Ho allegato la fonte pertinente qui. È inoltre possibile visualizzare tutte le fonti sul mio GitHub a: 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){ 
 
    \t console.log("Has game started? :"+hasStarted); 
 
    \t if(hasStarted==true){ 
 
    \t \t $('#choosecharacter').show(); 
 
    \t } 
 
    }); 
 
    }); 
 

 
    socket.on('client_disconnect', function (data) { 
 
    console.log(data); 
 
    }); 
 

 
    socket.on('client_counter', function (data) { 
 
    if(data<5){ 
 
\t  console.log(data); 
 
\t  incrementLoadBar(data); \t 
 
    \t allowedInGame=true; 
 
    } 
 
    if(!allowedInGame){ 
 
    \t ... 
 
    } 
 
    }); 
 

 
    socket.on('game_started', function (data) { 
 
    console.log(data); 
 
    $('#welcome').hide(); 
 
    $('#choosecharacter').show(); 
 
    }); 
 

 
    socket.on('set_user', function(characterName){ 
 
    \t chosenCharacter=characterName; 
 
    }); 
 

 
    socket.on('disable_player_choice', function(data){ 
 
    \t var id=data.stuff[0].chara; 
 
    \t incrementLoadBar(data.stuff[0].numChar); 
 
    \t console.log(id +" was chosen"); 
 
    \t $('#'+id).hide(); 
 
    }); 
 

 

 
//-------------------Gameplay functions 
 
    socket.on('start_gameplay',function(nonsense){ 
 
    \t showChanges(nonsense); 
 
\t $('#wait').hide(); 
 
\t $('#gamespace').show(); 
 
\t draw_c(); 
 
\t socket.emit('ready_to_play',chosenCharacter); 
 
    }); 
 

 
    socket.on('take_turn',function(updatedBoard){ 
 
    \t showChanges(updatedBoard); 
 
    \t if(updatedBoard.currPlayer==chosenCharacter){ 
 
    \t \t promptUser(updatedBoard); 
 
    \t } 
 
    }); 
 

 
    socket.on('roll_result',function(rollResult){ 
 
    \t promptUser(rollResult); 
 
    }); 
 

 
        ... 
 
        
 

 
\t $('#rollDiceButton').click(function(){ 
 
\t \t socket.emit('roll_dice',chosenCharacter); 
 
\t }); 
 

 
\t $('#okCloseButton').click(function(){ 
 
\t \t socket.emit('end_turn',chosenCharacter); 
 
\t }); 
 

 
\t $('.thumbnail').click(function(something){ 
 
\t \t socket.emit('player_chosen', something.target.id); 
 
\t \t    ... 
 
\t });

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)); 
 
    }); 
 
});

Si prega di essere gentile, Ho appena iniziato a utilizzare Node.js per circa una settimana fa. Grazie!

+0

Puoi pubblicare il messaggio di errore completo? – nha

+0

Domanda modificata per includerla, è: "events.js: 72 throw er; // evento 'error' non gestito RangeError: superata la dimensione massima dello stack di chiamate". – noden00b

risposta

27

Trovato il mio problema.

L'oggetto (temp) che stavo cercando di inviare tramite la rete (in socket.emit ('roll_result', temp);) era un array autoreferenziale. Era la proprietà ricorsiva dell'array che ha causato lo stack per superare la dimensione massima.

+0

Grazie per aver aggiunto la causa del problema, è stato eseguito lo stesso problema cercando di inviare un oggetto auto-ricorsivo su un socket.connessione io e non ero a conoscenza di cosa stava causando il superamento della dimensione massima dello stack delle chiamate! –

+0

Grazie mille! – patotoma

4

La risposta è molto utile. Grazie.

Ho appena avuto lo stesso problema e voglio condividere con chiunque possa incontrarlo.

Il mio codice usa express.js ed ha il seguente:

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

ha generato il "stack massimo di chiamata superato" errore. Il problema è che non dovrei inviare la variabile 'res' sul socketio al client. Immagino che causerà un comportamento ricorsivo se lo farò.

La soluzione è sufficiente rimuovere la 'res' dalla dichiarazione emettere:

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

Questo mi ha aiutato, dovrebbe essere la risposta corretta! –

0

Questo è lo stesso errore mi sono imbattuto, quando ho cliccato sul pulsante di invio. Si stava disattivando e lanciando "Dimensione massima dello stack delle chiamate superata". Ho riavviato il mio browser, ha funzionato .. Comportamento strano

Problemi correlati