ayou
Posted on January 23, 2024
Request without Keep-Alive
As we all know that in browsers, multi HTTP requests can resue a TCP connection with the HTTP header "connection: keep-alive;". But how to do in Node.js?
For example, here is a simple code snippet of requesting in Node.js:
// server.js
const http = require('http')
http
.createServer((req, res) => {
res.writeHead(200)
res.end('Hello World')
})
.listen(3000)
// client.js
const http = require('http')
function request() {
http
.request(
{
host: 'localhost',
port: 3000,
pathname: '/',
},
(res) => {
let buffer = []
res.on('data', (chunk) => {
buffer.push(chunk)
})
res.on('end', () => {
console.log(buffer.toString())
})
}
)
.end()
}
request()
setTimeout(() => {
request()
}, 1000)
When using wireshark to debug, we can find that the client port of two requets is different and there are two "Three-way Handshake" processes:
Request with Keep-Alive using http.Agent
Now, let's request with keep-alive using http.Agent, we only need to add a short piece of code:
const agent = new http.Agent({
keepAlive: true,
})
function request() {
http
.request(
{
agent,
host: 'localhost',
port: 3000,
pathname: '/',
},
() => {
// ...
}
)
.end()
}
But, the result of wireshark won't change! Actually, we need to specify the maxSockets
of the agent
:
const agent = new http.Agent({
keepAlive: true,
maxSockets: 1,
})
Why? Because maxSockets
indicats the max TCP connections that can be established per host. And the default value is Infinity
. If we don't set its value, a new connection will always be established for every request.
Now, let's change our code a little:
setTimeout(() => {
request()
}, 10000) // 1000 -> 10000
The wireshark will show:
The keep-alive didn't work again! And we can see that the server send a FIN packet in about 5s. So is there any parameter for server to control the timeout? Yes, that is keepAliveTimeout
,let's set it to 10s:
const http = require('http')
const server = http
.createServer((req, res) => {
res.writeHead(200)
res.end('Hello World')
})
.listen(3000)
server.keepAliveTimeout = 10000
And now the keep-alive works again.
Posted on January 23, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 15, 2024