request.reusedSocket
- <boolean> 请求是否通过重用的套接字发送。
当通过启用保持活动的代理发送请求时,可能会重用底层套接字。 但是如果服务器在不幸的时间关闭连接,客户端可能会遇到 'ECONNRESET' 错误。
const http = require('http');
// 服务器默认有 5 秒保持活动超时
http
.createServer((req, res) => {
res.write('hello\n');
res.end();
})
.listen(3000);
setInterval(() => {
// 调整保持活动代理
http.get('http://localhost:3000', { agent }, (res) => {
res.on('data', (data) => {
// 什么都不做
});
});
}, 5000); // 以 5 秒的间隔发送请求,因此很容易达到空闲超时
通过标记请求是否重用套接字,可以基于它进行自动错误重试。
const http = require('http');
const agent = new http.Agent({ keepAlive: true });
function retriableRequest() {
const req = http
.get('http://localhost:3000', { agent }, (res) => {
// ...
})
.on('error', (err) => {
// 检查是否需要重试
if (req.reusedSocket && err.code === 'ECONNRESET') {
retriableRequest();
}
});
}
retriableRequest();
- <boolean> Whether the request is send through a reused socket.
When sending request through a keep-alive enabled agent, the underlying socket might be reused. But if server closes connection at unfortunate time, client may run into a 'ECONNRESET' error.
const http = require('http');
// Server has a 5 seconds keep-alive timeout by default
http
.createServer((req, res) => {
res.write('hello\n');
res.end();
})
.listen(3000);
setInterval(() => {
// Adapting a keep-alive agent
http.get('http://localhost:3000', { agent }, (res) => {
res.on('data', (data) => {
// Do nothing
});
});
}, 5000); // Sending request on 5s interval so it's easy to hit idle timeout
By marking a request whether it reused socket or not, we can do automatic error retry base on it.
const http = require('http');
const agent = new http.Agent({ keepAlive: true });
function retriableRequest() {
const req = http
.get('http://localhost:3000', { agent }, (res) => {
// ...
})
.on('error', (err) => {
// Check if retry is needed
if (req.reusedSocket && err.code === 'ECONNRESET') {
retriableRequest();
}
});
}
retriableRequest();