Node.js http.request保持活动连接

4

我正在尝试在http.request上使用http.Agent({ keepAlive: true})来保持连接以备将来的请求。

我创建了一个简单的服务器来记录每个新连接,但是当我运行我的request.js时,服务器会记录两个新连接。

如何在Node.js本地模块中使用HTTP keep-alive?

request.js:

Original Answer翻译成"最初的回答"

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);

输出:

NEW CONNECTION
REQUEST
NEW CONNECTION
REQUEST
4个回答

5

可以通过以下方式设置 maxSockets 选项:

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

默认情况下,maxSockets设置为Infinity - https://nodejs.org/api/http.html#http_new_agent_options

在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();

我得到了相同的结果,但现在“REQUEST_2”被延迟了。似乎第二个请求正在等待第一个请求关闭。 - isflavior
2
谢谢。现在它可以工作了,我之前没有处理请求的“data”和“end”事件。 - isflavior
为什么在不处理请求的事件"data"和"end"时,它不能正常工作(即使仅使用'noop')? - Andrea Franchini
2
解释在这里:https://nodejs.org/dist/latest-v10.x/docs/api/http.html#http_class_http_clientrequest,从“If no 'response' handler is added”开始。在此情况下,您可以省略end事件,但我已将其添加以覆盖所有情况。 - kuba

0
已接受的答案没有明确说明发布的代码每个主机每个线程只允许一个请求。 通常这不是你想要的,会导致请求减速等待前一个请求完成。

这是一条有帮助的说明,但它应该是对其他答案的评论,而不是一个独立的答案。它本身并不能回答问题。 - mactyr

0

从Node.js v19开始,所有的HTTP(s)出站连接默认情况下都将启用keepAlive选项。

您可以在Node.js v19文档中了解更多相关信息。


0

你的演示没有设置 data 监听器的 res1,这会导致套接字无法关闭,因此第二个请求必须创建一个新的连接到服务器,只需添加一个 data 监听器即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接