nod*_*00b 11 javascript node.js socket.io
对于我的Node应用程序,我在Debian上运行了一个服务器(app.js),使用socket.io向我的客户端(index.html)提供html和websocket数据.我正在尝试制作基于回合制的HTML5多人游戏.
在使用socket.emit()/ io.emit()和socket.on()执行大量成功的数据传输后,我的服务器在socket.emit()调用时崩溃,错误为
"events.js:72
throw er; //未处理的'错误'事件
RangeError:超出最大调用堆栈大小".
我有很多socket.on()事件监听器,每个都处理游戏中的不同功能(例如roll_dice,end_turn,ready_to_play等).
我试图研究这个问题(发现很多关于异步循环的讨论),但是无法找到如何将解决方案应用到我自己的代码中.我在这里附上相关来源.您还可以在我的github上查看所有源代码: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);
...
});Run Code Online (Sandbox Code Playgroud)
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));
});
});Run Code Online (Sandbox Code Playgroud)
请温柔,我刚开始使用Node.js一周前.谢谢!
nod*_*00b 45
找到了我的问题.
我试图通过网络发送的对象(temp)(在socket.emit('roll_result',temp);)是一个自引用数组.这是数组的递归属性导致堆栈超过最大大小.
小智 6
答案非常有帮助.谢谢.
我刚遇到同样的问题,想与可能遇到它的人分享.
我的代码使用express.js并具有以下内容:
io = require('socket.io').listen(server);
......
io.to(socketId).emit('hello', {userId:userId, data:data, res:res});
Run Code Online (Sandbox Code Playgroud)
它生成了"超出最大调用堆栈"错误.问题是我不应该通过socketio将变量'res'发送给客户端.我想如果我这样做会导致一些递归行为.
解决方案是从emit语句中删除'res':
io.to(socketId).emit('hello', {userId:userId, data:data});
Run Code Online (Sandbox Code Playgroud)