14

I am trying to set-up a HTTP client to keep the underlying connection open (keep-alive) in node.js, but it seems that the behaviour does not correspond to the docs (http://nodejs.org/api/http.html#http_class_http_agent).

I am creating a new HTTP agent, setting the maxSockets property to 1 and requesting an url (for instance http://www.twilio.com/) every second.

It seems that on every request the socket is closed and a new socket is created. I have tested this with node.js 0.10.25 and 0.10.36 under Ubuntu 14.04.

Has anyone been able to get keep alive to work?

Here is the code:

var http = require("http");

var agent = new http.Agent();
agent.maxSockets = 1;

var sockets = [];

function request(hostname, path, callback) {
    var options = {
        hostname: hostname,
        path: path, 
        agent: agent, 
        headers: {"Connection": "keep-alive"}
    };
    var req = http.get(options, function(res) {
        res.setEncoding('utf8');
        var body = "";
        res.on('data', function (chunk) {
            body += chunk;
        });
        res.on('end', function () {
            callback(null, res, body);
        });
    });
    req.on('error', function(e) {
        return callback(error);
    });
    req.on("socket", function (socket) {
        if (sockets.indexOf(socket) === -1) {
            console.log("new socket created");
            sockets.push(socket);
            socket.on("close", function() {
                console.log("socket has been closed");
            });
        }
    });
}

function run() {
    request('www.twilio.com', '/', function (error, res, body) {
        setTimeout(run, 1000);
    });
}

run();
quentinadam
  • 3,058
  • 2
  • 27
  • 42
  • What does `console.dir(res.headers.connection)` show inside your `http.get()` callback? – mscdex Jan 30 '15 at 04:23
  • I had already checked that, and the host returns "Connection: keep-alive" header in the response, indicating that it does accept to keep the connection open. – quentinadam Jan 30 '15 at 05:25

3 Answers3

14

If I'm not mistaken the connection pool was implemented in 0.12.

So if you want to have a connection pool prior 0.12 you can simply use the request module:

var request = require('request')
request.get('www.twilio.com', {forever: true}, function (err, res, body) {});

If you are using node 0.12+ and you want to use the HTTP core module directly, then you can use this to initialize your agent:

var agent = new http.Agent({
  keepAlive: true,
  maxSockets: 1,
  keepAliveMsecs: 3000
})

Notice the keepAlive: true property, that is required to keep the socket open.

You can pass an agent to the request module as well, again that works only on 0.12+ otherwise it defaults to internal pool implementation.

simo
  • 15,078
  • 7
  • 45
  • 59
  • Obviously though, at the time of my post, the latest stable version of Node.js was 0.10, and the docs I was linking to where the 0.10 docs. Thanks for the answer, I will give it a try when I get a chance (I had meanwhile implemented a workaround). – quentinadam Nov 04 '15 at 06:17
  • I didn't even noticed the post date. Anyway, still my answer is valid. – simo Nov 04 '15 at 06:20
0

I guess it should work on node 0.12+. You may also want to use a different agent for this purpose. For example keep-alive-agent can do what you want:

var KeepAliveAgent = require('keep-alive-agent'),
    agent = new KeepAliveAgent();
advncd
  • 3,787
  • 1
  • 25
  • 31
0

The below worked for me in meteor which uses the npm module for keepaliveagent

var agent = new KeepAliveAgent({ maxSockets: 1 });

var options = {
  agent:agent,
  headers: {"Connection":"Keep-Alive"}
}

try {
  var client = Soap.createClient(url);

  var result = client.myfirstfunction(args,options);

//process result
  result = client.mysecondfunction(args,options);

}

Both the method calls returns data in one socket connection. You pass the options in each method call