Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why the http client does not support the keep alive feature? #33853

Closed
masx200 opened this issue Jun 12, 2020 · 4 comments
Closed

Why the http client does not support the keep alive feature? #33853

masx200 opened this issue Jun 12, 2020 · 4 comments
Labels
invalid Issues and PRs that are invalid.

Comments

@masx200
Copy link
Contributor

masx200 commented Jun 12, 2020

Why the http client does not support the keep alive feature?

TCP socket should be reused in multiple requests.

But the result is that the request and response are sent only once per connection.

  • Version:

nodejs v14.2.0

  • Platform:

Linux localhost 4.9.148 #1 SMP PREEMPT Tue Mar 10 02:27:59 CST 2020 aarch64 Android

  • Subsystem:

What steps will reproduce the bug?

client.js

 const http = require('http');
const agent = new http.Agent({
    keepAlive: true,
    keepAliveMsecs: 10000
});
function request() {
    count++;
    
    const req = http.request({
        host: 'localhost',
        port: 9000,
        method: 'GET',
        agent: agent
    }, res => {
        const socket = res.socket;
        console.log(socket.localAddress, socket.localPort);
        console.log(res.headers);
    });
    req.end();
    if (count > 20) {
        process.exit();
    }
}
let count = 0;
setInterval(() => {
    request();
    request();
}, 500 * (1 + Math.random()));
setInterval(() => {
    request();
}, 500 * (1 + Math.random()));
setInterval(() => {
    request();
}, 500 * (1 + Math.random()));

server.js

 const http = require('http');
http.createServer((req, res) => {
    const socket = req.socket;
    const info = socket.remoteAddress + ',' + req.socket.remotePort;
    console.log(info);
    console.log(req.headers);
    res.write(JSON.stringify(req.headers));
    res.end(info);
}).listen(9000, () => {
    console.log('listening');
});
node server.js
node client.js

How often does it reproduce? Is there a required condition?

100%

What is the expected behavior?

TCP socket should be reused in multiple requests.

What do you see instead?

$ node /storage/emulated/0/test/server.js
listening
::ffff:127.0.0.1,44284
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44286                                  
{ host: 'localhost:9000', connection: 'keep-alive' }    
::ffff:127.0.0.1,44288
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44290
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44294
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44296
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44300
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44302
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44304
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44308
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44310
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44312
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44314
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44318
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44320
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44322
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44324
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44328
{ host: 'localhost:9000', connection: 'keep-alive' }
::ffff:127.0.0.1,44330
{ host: 'localhost:9000', connection: 'keep-alive' }
^C
$
$ node /storage/emulated/0/test/client.js


127.0.0.1 44284
{
  date: 'Fri, 12 Jun 2020 04:22:52 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}


127.0.0.1 44286
{
  date: 'Fri, 12 Jun 2020 04:22:52 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}
127.0.0.1 44288
{
  date: 'Fri, 12 Jun 2020 04:22:52 GMT',                
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}
127.0.0.1 44290
{
  date: 'Fri, 12 Jun 2020 04:22:52 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}

127.0.0.1 44294
{
  date: 'Fri, 12 Jun 2020 04:22:52 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}

127.0.0.1 44296
{
  date: 'Fri, 12 Jun 2020 04:22:53 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}


127.0.0.1 44300
{
  date: 'Fri, 12 Jun 2020 04:22:53 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}
127.0.0.1 44302
{
  date: 'Fri, 12 Jun 2020 04:22:53 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}

127.0.0.1 44304
{
  date: 'Fri, 12 Jun 2020 04:22:53 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}

127.0.0.1 44308
{
  date: 'Fri, 12 Jun 2020 04:22:53 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}

127.0.0.1 44310
{
  date: 'Fri, 12 Jun 2020 04:22:53 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}


127.0.0.1 44312
{
  date: 'Fri, 12 Jun 2020 04:22:54 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}
127.0.0.1 44314
{
  date: 'Fri, 12 Jun 2020 04:22:54 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}

127.0.0.1 44318
{
  date: 'Fri, 12 Jun 2020 04:22:54 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}

127.0.0.1 44320
{
  date: 'Fri, 12 Jun 2020 04:22:54 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}


127.0.0.1 44322
{
  date: 'Fri, 12 Jun 2020 04:22:54 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}
127.0.0.1 44324
{
  date: 'Fri, 12 Jun 2020 04:22:54 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}

127.0.0.1 44328
{
  date: 'Fri, 12 Jun 2020 04:22:54 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}

127.0.0.1 44330
{
  date: 'Fri, 12 Jun 2020 04:22:55 GMT',
  connection: 'keep-alive',
  'transfer-encoding': 'chunked'
}


$

Additional information

@masx200 masx200 changed the title Why the http client does not support the keep alive feature.? Why the http client does not support the keep alive feature? Jun 12, 2020
@DerekNonGeneric
Copy link
Contributor

I think this is traditionally solved as is described on the following page.

https://www.jstips.co/en/javascript/working-with-websocket-timeout/

At least that's how I've solved it for myself, anyone else please feel free to add 2¢.

@masx200
Copy link
Contributor Author

masx200 commented Jun 12, 2020

@Flarna

Thanks, you found the correct answer to the question.

@Flarna
Copy link
Member

Flarna commented Jun 12, 2020

I think you have to consume the response data received on client side. Try adding res.resume() if you are not interested in the response data in your sample.
Please note that this is done automatically if no response callback is set at all (see https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_class_http_clientrequest)

@bnoordhuis
Copy link
Member

Closing as answered.

@bnoordhuis bnoordhuis added the invalid Issues and PRs that are invalid. label Jun 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid Issues and PRs that are invalid.
Projects
None yet
Development

No branches or pull requests

4 participants