套接字IO:RangeError:超出最大调用堆栈大小

时间:2016-10-07 12:48:23

标签: javascript node.js sockets websocket

每次客户端连接到我的nodejs服务器时,我的服务器崩溃时出现错误“RangeError:超出最大调用堆栈大小”。我相信我必须在某个地方有一个递归问题,但这是在逃避我。

我的服务器:

require('monitor').start();
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 allClients = [];

io.on('connection', function(socket){
  console.log('user joined: ' + socket.request.connection.remoteAddress + ':' + socket.request.connection.remotePort);
  socket.address = socket.request.connection.remoteAddress;
  socket.port = socket.request.connection.remotePort;
  socket.name = '';
  socket.xPos = 0;
  socket.yPos = 0;
  //io.emit('new user', socket.address + '_' + socket.port);

  // Send current client list to new connection
  socket.emit('client list', allClients);

  // Only send 'new user' event to previously connected clients, not the new client.
  var i = 0;
  for(i=0;i<allClients.length;i++){
    allClients[i].emit('new user', socket.address + '_' + socket.port);
  }

  // Push new socket into the client array after the array has been sent to all other users
  allClients.push(socket);

  socket.on('chat message', function(msg){
    io.emit('chat message', socket.address + ':' + socket.port + ": " + socket.name + ' says: ' + msg);
    console.log(socket.address + ":" + socket.port + ": " + socket.name + ' says: ' + msg);
  });

    socket.on('set_name', function(msg){
    //io.emit('chat message', socket.address + ':' + socket.port + ': ' + msg);
    socket.name = msg;
    console.log(socket.address + ":" + socket.port + ' set name to: ' + msg);
  });

  socket.on('xPosUpdate', function(msg){
    //io.emit('chat message', socket.address + ':' + socket.port + ': ' + msg);
    console.log(socket.address + ":" + socket.port + ' set xPos to: ' + msg);
  });

  socket.on('yPosUpdate', function(msg){
    //io.emit('chat message', socket.address + ':' + socket.port + ': ' + msg);
    console.log(socket.address + ":" + socket.port + ' set yPos to: ' + msg);
  });

  socket.on('disconnect', function() {
    io.emit('user disconnect', socket.address + '_' + socket.port);
    io.emit('chat message', socket.address + ':' + socket.port + ": " + socket.name + ' disconnected.');
      console.log('Got disconnect!');
    socket = null;
      var i = allClients.indexOf(socket);
      allClients.splice(i, 1);
   });
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

然后在客户端处理套接字:

var users = [];
      $('#chatInput').submit(function(){
        socket.emit('chat message', $('#m').val());
        $('#m').val('');
        return false;
      });
        $('#nameInput').submit(function(){
        socket.emit('set_name', $('#n').val());
        $('#n').val('');
        return false;
      });
            socket.on('client list', function(msg){
        $('#messages').append($('<li>').text('Processing client list...'));
                var i = 0;
              for(i=0;i<msg.length;i++){
                $('#messages').append($('<li>').text('Client ' + i + ': ' + msg[i].address + ':' + msg[i].port + ', Name: ' + msg[i].name));
              }
      });
      socket.on('chat message', function(msg){
        $('#messages').append($('<li>').text(msg));
      });
            socket.on('user disconnect', function(msg){
        users[msg].unset();
      });
            socket.on('new user', function(msg){
                users[msg] = [];
                users[msg].xPos = 0;
                users[msg].yPos = 0;
        $('#messages').append($('<li>').text(msg));
      });

3 个答案:

答案 0 :(得分:2)

感谢您的回复。

经过一些实验后,我意识到溢出错误是由于我试图在服务器上的以下行中发出的数据量而触发的:

socket.emit('client list', allClients);

当新用户连接时,我将整个连接对象推送到&#34; allClients&#34;阵列。连接对象中包含的数据量太大,无法通过 socket.emit 发送,并导致RangeError。

我将不得不简化发送到每个新客户端的客户端列表数据,以避免这种情况......&#34;堆栈溢出&#34; ..:)

答案 1 :(得分:0)

您可以使用此代替您的循环(这将是相同的结果):

socket.broadcast.emit('new user', socket.address + '_' + socket.port);

然后你可以删除这部分:

socket = null;
var i = allClients.indexOf(socket);
allClients.splice(i, 1);

但我不确定这是不是问题。 我在猜你的socket.name = msg;。我不确定你是否能够更新这个对象。删除它最好。

答案 2 :(得分:-1)

AnyObject

上面的代码示例对我来说有点怀疑。你检查了allClients.length的值吗?作为旁注,为什么要将i的值初始化两次?变量