2016-10-07 2 views
1

Каждый раз, когда клиент подключается к моему серверу nodejs, мой сервер выходит из строя с ошибкой «RangeError: максимальный размер стека вызовов превышен». Я считаю, что у меня должна быть рекурсивная проблема, но она ускользает от меня.Socket IO: 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)); 
     }); 
+0

Я уверен, что это связано с вашей 'for' петли, но не имеют времени для проверки – DrakaSAN

ответ

2

Благодарим за ответы.

После недолгих экспериментов я понял, что ошибка переполнения был запуск из-за объема данных, я пытал испускают в следующей строке на сервере:

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

Когда новый пользователь подключается Я толкаю весь объект подключения в массив «allClients». Количество данных, содержащихся в объекте соединения, слишком велико для отправки через socket.emit и вызвало RangeError.

мне придется упростить данные списка клиентов, излучаемых каждому новому клиенту, чтобы избежать этого ... «переполнение стека» .. :)

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

выше пример кода выглядит немного подозрительной для меня. Вы проверили значение allClients.length? Как заметка на полях почему инициализируются значение я дважды переменной

0

Вместо вашего цикла вы можете использовать это (это будет тот же результат):

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

, то вы можете удалить эту часть:

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

Но я не уверен, что это проблема. Я догадываюсь о вашем socket.name = msg;. Я не уверен, что вы можете обновить этот объект. Лучше удалить это.