【问题标题】:why I can only send 5 request if I don't listen the data event?如果我不监听数据事件,为什么我只能发送 5 个请求?
【发布时间】:2015-01-12 08:18:18
【问题描述】:

我发现了一些似乎与这个问题有关系的问题(例如:Why is node.js only processing six requests at a time?),但我仍然无法理解细节。

以下是我的情况。

首先,服务器的代码:

var express = require ('express'),
    methodOverride = require('method-override');

var app = express();

app.use(methodOverride());
app.use(function(err, req, res, next) {
    console.error(err.stack);
    res.status(500);
    res.send({ error: err });
});

app.use('/', function(req, res, next) {
    res.header('Cache-control', 'no-cache');
    res.header('Access-Control-Allow-Origin', '*');
    next();
});

app.get('/OK/', function (req, res) {
    console.log(getTimestamp() + ' OK ');
    res.status(200).send("200");
});

app.listen(22222);

function getTimestamp(){
    var timestamp = new Date();
    return timestamp.toString() + " " + timestamp.getMilliseconds();
}

console.log(getTimestamp() + ' Sever started!');

然后是客户端的代码:

var http = require('http');

var opt = {
    method: "GET",
    host: "localhost",
    port: 22222,
    path: "/OK/",
    headers: {
        'Cache-control': 'no-cache'
    }
};

count = 10;
function request(){
    var req = http.request(opt, function (serverFeedback) {
        var body = "";
        serverFeedback
            .on('data',function(){})
            .on('end', function () {
                console.log(getTimestamp(), "response END", serverFeedback.statusCode, body);
        });
    });
    req.end();

    console.log(getTimestamp(), "resuest START");
    count--;
    if(count > 0){
        setTimeout(request, 500);
    }
}

request();

function getTimestamp(){
    var timestamp = new Date();
    return timestamp.toString() + " " + timestamp.getMilliseconds();
}

在node中运行它们,当然先运行server,客户端大约5s会发送10个请求,一切正常。像这样:

但是,如果我删除有关在客户端监听“数据”事件的代码,如下所示:

var req = http.request(opt, function (serverFeedback) {
    var body = "";
    serverFeedback
        //.on('data',function(){})      /* remove the listener*/
        .on('end', function () {
            console.log(getTimestamp(), "response END", serverFeedback.statusCode, body);
    });
});

再次运行,客户端似乎在 5s 内发送了 10 个请求,但实际上,服务器只收到了 5 个请求:

如您所见,“结束”事件似乎没有触发。

最后,我通过服务器的代码在响应中添加了一个标头:

app.use('/', function(req, res, next) {
    res.header('Cache-control', 'no-cache');
    res.header('Access-Control-Allow-Origin', '*');
    res.header('connection', 'close');      /* add a header about connection */
    next();
});

重启服务器并再次运行客户端:

现在服务器可以立即接收到所有 10 个请求,但是“结束”事件似乎仍然没有触发。

所以,“data”事件的监听器似乎对http连接产生了一些影响。

谁能给大家解释一下细节?

【问题讨论】:

    标签: javascript node.js http


    【解决方案1】:

    有两件事正在发生。

    首先,当您不“监听数据事件”时,响应流永远不会完成,因此您发出的 http 请求永远不会完成。这本质上是一个泄漏。 始终使用您的流!!!否则,您的流将无限期地处于“暂停”状态。

    第二个是 node.js 默认使用默认代理 http://nodejs.org/api/http.html#http_class_http_agent 连接池。现在,它汇集了 5 个连接,这就是为什么您会看到 5 个连接的限制。

    【讨论】:

    • 我知道nodejs池只有5个连接,但是如果我已经监听了“data”事件,并且设置响应头“connection”值“keep-alive”,服务器可以接收到所有10个立即请求。这是否意味着保持连接或不仅取决于是否侦听“数据”事件,并且独立于响应中的“连接”标头?您说如果没有“数据”事件的侦听器,http 请求永远不会完成,这本质上是一个泄漏。您能否为您的观点提供一些依据?非常感谢您的回复!
    猜你喜欢
    • 2011-03-15
    • 2016-04-02
    • 2021-03-14
    • 2011-03-03
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 2015-08-18
    相关资源
    最近更新 更多