Reputation: 607
Every time a client connects to my nodejs server, my server crashes with the error 'RangeError: Maximum call stack size exceeded'. I believe I must have a recursive issue somewhere, but it is eluding me.
My server:
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');
});
And then handling the socket on the client side:
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));
});
Upvotes: 2
Views: 3655
Reputation: 607
Thank you for the responses.
After a bit of experimentation I realized the overflow error was triggering due to the volume of data I was attempting to emit in the following line on the server:
socket.emit('client list', allClients);
When a new user connects I am pushing the entire connection object into the "allClients" array. The amount of data contained in a connection object is too large to be sent via socket.emit and caused the RangeError.
I will have to simplify the client list data being emitted to each new client to avoid this..."stack overflow".. :)
Upvotes: 4
Reputation: 4453
Instead of your loop you may use this (this will be the same result) :
socket.broadcast.emit('new user', socket.address + '_' + socket.port);
then you can remove this part:
socket = null;
var i = allClients.indexOf(socket);
allClients.splice(i, 1);
But I'm not sure it is the problem.
I'm guessing about your socket.name = msg;
. I'm not really sure you are able to update this object. It's better to remove this.
Upvotes: 0
Reputation: 85
// 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);
}
The above code sample looks a bit suspicious to me. Did you check the value of allClients.length? As a sidenote why initialise the value of i twice?variable
Upvotes: -1