5

I'm trying to use http.Agent({ keepAlive: true}) on http.request to keep the connection open for future requests.

I created a simple server to log each new connection but when i run my request.js the server logs two new connections.

How can i use the HTTP keep-alive with Node.js native modules?

request.js:

const http = require("http");

const agent = new http.Agent({
    keepAlive: true
});

var req1 = http.request({
    agent: agent,
    method: "GET",
    hostname: "localhost",
    port: 3000
}, function (res1) {
    console.log("REQUEST_1");

    var req2 = http.request({
        agent: agent,
        method: "GET",
        hostname: "localhost",
        port: 3000
    }, function (res2) {
        console.log("REQUEST_2");
    });

    req2.end();
});

req1.end();

server.js:

const http = require('http');

var server = http.createServer(function (req, res) {
    res.end('OK');
    console.log("REQUEST");
})

server.on('connection', function (socket) {
    console.log("NEW CONNECTION");
})

server.listen(3000);

output:

NEW CONNECTION
REQUEST
NEW CONNECTION
REQUEST

4 Answers 4

6

Set maxSockets options like this:

const agent = new http.Agent({
    keepAlive: true,
    maxSockets: 1
});

By default maxSockets is set to Infinity - https://nodejs.org/api/http.html#http_new_agent_options

Full example on node v10

const http = require("http");

const agent = new http.Agent({
    keepAlive: true,
    maxSockets: 1
});

var req1 = http.request({
    agent: agent,
    method: "GET",
    hostname: "localhost",
    port: 3000
}, function (res1) {
    console.log("REQUEST_1");

    res1.on('data', function () {
        console.log("REQUEST_1 data");
    });

    res1.on('end', function () {
        console.log("REQUEST_1 end");
    });

    var req2 = http.request({
        agent: agent,
        method: "GET",
        hostname: "localhost",
        port: 3000
    }, function (res2) {
        console.log("REQUEST_2");

        res2.on('data', function () {
            console.log("REQUEST_2 data");
        });

        res2.on('end', function () {
            console.log("REQUEST_2 end");
        });
    });
    req2.end();
});
req1.end();
Sign up to request clarification or add additional context in comments.

4 Comments

I got the same result, however now the "REQUEST_2" was delayed. It seems like the second request is waiting for the first one to close.
Thanks. Now its working, i was not handling the events ''data' and 'end' of the requests.
Why it doesn't work without handling (even a 'noop' is fine) the events 'data' and 'end' of the requests?
The explenation is here: nodejs.org/dist/latest-v10.x/docs/api/… , starts with "If no 'response' handler is added". You can omit end event in this case but I've added this to cover it all.
5

Starting with Node.js v19, the keepAlive option is set to true by default for all outgoing HTTP(s)/1.1 connections.

You can read more about it on Node.js's v19 documentation.

2 Comments

Thank you @Stanley. they say for "HTTP(S)/1.1". Do you know if this also applies to HTTPS/2 ?
I haven't seen anything in the documentation indicating that it also applies to HTTP(S)/2. I’ve updated the answer to clarify that—thanks for the question!
0

The accepted answer doesn't make clear that the code posted will allow only one request simultaneously per host per thread.

That is usually not what you want and will lead to requests slowing down waiting for the previous one to complete.

1 Comment

This is a helpful clarification, but it should really be a comment on the other answer, not an answer of its own. By itself, it does not answer the question.
0

your demo not set res1's on data listener ,it will cause the socket not be close ,so the second request have to create a new connect to server ,just add a data listener

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.