在Node.js HTTP Server上重用TCP连接

时间:2012-04-20 14:06:57

标签: http node.js proxy keep-alive

我正在使用默认http.Server模块的http个对象( - > API)。

如果客户端连接,则request事件由服务器发出,并且http.ServerRequest对象将传递给事件处理程序。该请求对象发出以下三个事件:

  • 数据(传入数据)
  • 结束(请求已结束)
  • 关闭(连接关闭)

我希望保留客户端的初始(TCP)连接,并将其重用于多个请求。客户端在发送“Connection:keep-alive”标头时支持此行为。

但是如何使用node.js实现这一点?我的问题是在第一次请求之后发出 end 事件,就像官方API说的那样:

  

每个请求只发出一次。在那之后,没有更多'数据'   将根据请求发出事件。

好的,我无法使用该请求。但有没有办法处理相同的TCP连接并在其上创建新请求?

背景:我正在开发代理实现。如果用户访问使用NTLM 的网站,我必须至少为这种类型的身份验证所需的三个客户端请求保留一个连接,以免遇到this问题。

你知道我会尝试什么吗?

提前致谢!

1 个答案:

答案 0 :(得分:0)

当我使用节点v6.17运行此代码时,它建议保持活动状态

function notifyNotKeptAlive(httpObject, eventName, httpObjectName){
    httpObject.on(eventName, function(socket){
        socket.on('close', function(){
                console.log("Yeeouch !  "+httpObjectName+" connection was not kept alive!");
        });
    });
}
var http=require('http');
var count=1;
var srv = http.createServer(function (req, res) {
    var secs;
    if ( (count%2)==1){secs=3;}
    else {secs=1;}
    console.log("Got http request #"+count+" so server waits "+secs+" seconds to respond");
    var countForThisClosure=count;
    setTimeout(function(){
        console.log("Waking up from sleep of "+secs);
        res.writeHead(200, {'Content-Type': 'text/plain'});
        if (secs===3){
            res.end('Visit #'+countForThisClosure+' costing a wait of '+secs+' seconds !!');
        } else {
            res.end('Visit #'+countForThisClosure+' costing a wait of '+secs+' seconds !!');
        }
    }, secs*1000);
    count++;
}).listen(8090);

notifyNotKeptAlive(srv, 'connection', 'http server');

for (var i=0;i<2;i++){
    var req=http.request( {'host': 'localhost', 'port':8090}, function (res) {
        res.setEncoding('utf8');
        res.on('data', function (chunk) {
            console.log('INCOMING <---' + chunk);
        });
        }
    );
    notifyNotKeptAlive(req, 'socket', 'http client');
    req.end();
}

只有在我向Epeli帮助提供的http lib源的第1263行添加感叹号时,IT才有效。因此下面的行显示“if(req.shouldKeepAlive){”应该改为“if(!req.shouldKeepALive){” res.on('end',function(){

if (req.shouldKeepAlive) {
      socket.removeListener('close', closeListener);
      socket.removeListener('error', errorListener);
      socket.emit('free');
    }
  });

此行位于从第1113行开始的ClientRequest.prototype.onSocket闭包中设置的on'end'回调中。

此http lib源代码的链接(与Epeli相同)https://github.com/joyent/node/blob/e8067cb68563e3f3ab760e3ce8d0aeb873198f36/lib/http.js#L889