当前位置: 首页 > 知识库问答 >
问题:

超过node.js+socket.io最大调用堆栈大小

赖绪
2023-03-14

对于我的节点应用程序,我有一个运行在Debian上的服务器(app.js),它使用socket.io向我的客户机(index.html)提供html和websocket数据。我正在尝试制作一个回合制的HTML5多人游戏。

在使用socket.emit()/io.emit()和socket.on()成功执行了多次数据传输后,我的服务器在socket.emit()调用上崩溃,出现错误
“events.js:72
throw er;//unhandled'error'event
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);
		            ...
	});

null

应用程序JS

null

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

null

请温柔点,我大约一周前才开始使用Node.js。谢谢!

共有1个答案

符鸣
2023-03-14

找到我的问题了。

我试图通过网络发送的对象(temp)(在socket.emit('roll_result',temp)中)是一个自引用数组。导致堆栈超过最大大小的是数组的递归属性。

 类似资料:
  • 问题内容: 当我运行我的代码时,Node.js引发由过多的递归调用引起的异常。我试图将Node.js堆栈大小增加,但是Node.js崩溃而没有任何错误消息。当我不使用sudo再次运行此命令时,Node.js将输出。是否有可能在不删除递归调用的情况下解决此问题? 问题答案: 您应该将递归函数调用包装到 , 要么 函数使node.js有机会清除堆栈。如果您不这样做,并且有很多循环没有任何 真正的 异步

  • //{this.props.params.item}来自反应路由器(路径('/detail/item/id')) 为什么我的调度是无限循环,直到出错(超过最大调用堆栈大小)

  • 问题内容: 我无法终生弄清楚为什么我会出错: 超过最大呼叫堆栈大小 运行此代码时。如果我注释掉: 错误消失了。我什至已注释掉其他电话,以尝试缩小问题的出处。 代码(删除了额外的功能): 问题答案: 由于此循环: 您正在从render调用getTabs方法,并在其中进行操作,将触发重新渲染,再次是getTabs ..... 无限循环 。 从方法中删除,它将起作用。 另一个问题在这里: 我们需要为on

  • 问题内容: 我有一台服务器,可能导致以下输出死亡: 但是,如果没有堆栈转储或跟踪,就无法确定这是无限递归还是只是链太大而已,更不用说问题函数在哪里了。 使用该选项运行Node 不仅使我的测试运行缓慢(正如人们期望的那样),而且没有重现该问题。 有人有任何解决方案或提示来深入了解此问题吗? 问题答案: 看来目前的答案是:站稳脚步,等待Node.js更新到新的V8版本,或者使用此Chromium项目错

  • 问题内容: 我想这意味着有一个循环引用,但是对于我的一生,我无法猜测如何解决它。 有人有主意吗? http://plnkr.co/edit/aNcBcU?p=预览 检查Chrome中的调试控制台(例如),您将看到错误。冒犯的行是 通过以下方式在控制器上对scope.map进行“ $ watched” 问题答案: 这是因为您要比较对象是否相等,而不是参考。将您的声明更改为此:

  • 如果用户未登录,我尝试将用户重定向到“TrapPage”。 这是我的代码: 当我将函数requireAuth放在onEnter上时,控制台给我一个错误: 我是一个反应迟钝的人,请耐心点:) 我的代码有什么问题?