Jean Bon
Jean Bon

Reputation: 45

Socket IO infinite loop over 1000 connections

I need to benchmark multiples socket connections. I've got a nodejs server with this following code :

var io = require('./lib/node_modules/socket.io').listen(12345)

io.sockets.on("connect", function(socket) {
    console.log("Socket " + socket.id + " connected.")

    socket.on("disconnect", function() {
        console.log("Socket " + socket.id +" disconnected.")
    })
})

and a nodejs client :

var port            = 12345
,   nbSocket        = 1000
,   io              = require("./lib/node_modules/socket.io-client")

for (var i = 1;i <= nbSocket;i++)
{
    var socket = io.connect("http://<<my_ip>>:" + port, {forceNew: true})
}

When client code was executed, server correctly connects sockets and ends normally.

But if we change nbSocket to 2000, server never ends connecting and disconnecting sockets.

We already tried to change the limit with :

ulimit -n5000

But it didn't worked. Is there another limit somewhere or something we missed ?

Upvotes: 2

Views: 3455

Answers (1)

Lucio Paiva
Lucio Paiva

Reputation: 20836

I tested on OSX running Node v0.12.4 and socket.io v1.3.5 and it started to cause me problems around nbSocket=5000.

Try appending this snippet to the end of your server script:

process.on('uncaughtException', function(err) {
    console.info(util.inspect(err, {colors: true}));
});

Also, I changed your code a little and added a timer that twice every second prints the number of open sockets:

var
    util = require('util'),
    io = require('socket.io').listen(12345);

var
    clientCount = 0;

function onClientDisconnect() {
    clientCount--;
}

io.on('connect', function(socket) {
    clientCount++;
    socket.on('disconnect', onClientDisconnect);
});

console.info('Listening...');

setInterval(function () {
    console.info('Number of open sockets: %d', clientCount);
}, 500);

process.on('uncaughtException', function(err) {
    console.info(util.inspect(err, {colors: true}));
});

When the number of open sockets started to get close to 5000, I started seeing these 2 messages several times:

{ [Error: accept ENFILE] code: 'ENFILE', errno: 'ENFILE', syscall: 'accept' }
{ [Error: accept EMFILE] code: 'EMFILE', errno: 'EMFILE', syscall: 'accept' }

According to libc manual:

  • ENFILE: too many distinct file openings in the entire system
  • EMFILE: the current process has too many files open

So in fact my problem was the limit of file descriptors, so check if it's also your problem by appending the above snippet to your server script. If the exceptions appear, you should investigate how to properly increase the limit of open files in your system.

Upvotes: 1

Related Questions