在Node.js HTTP服务器上重复使用TCP连接

6
我正在使用默认的http模块中的http.Server对象(-> API)。
如果客户端连接,则服务器将发出request事件,并将http.ServerRequest对象传递给事件处理程序。该请求对象会发出以下三个事件:
- data(传入数据) - end(请求结束) - close(连接关闭)
我想保留客户端的初始(TCP)连接,并重用它来进行多个请求。客户端支持此行为,因为它发送“Connection:keep-alive”头。
但是,如何在node.js中实现这一点呢?我的问题是,在第一个请求之后,就会发出end事件,并且正如官方API所说的那样:
发出每个请求时仅一次。之后,将不会在请求上发出“data”事件。
好的,我不能使用该请求。但是有没有任何方法可以在同一TCP连接上工作并创建新请求?
背景:我正在开发一个代理实现。如果用户访问的网站使用 NTLM,我必须至少为该类型的身份验证保持一个连接,以避免遇到 this 问题。
你有什么想法吗?
提前致谢!

据我所知,Node.js使用代理进行连接重用。我认为你应该从这里检查http lib源代码:https://github.com/joyent/node/blob/e8067cb68563e3f3ab760e3ce8d0aeb873198f36/lib/http.js#L889 - esamatti
代理仅用于客户端请求,并且我需要在服务器端实现这种行为。尽管如此,你说得没错,代理负责关闭外部连接。 - muffel
1个回答

0
当我使用Node 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 行添加感叹号时,它才能正常工作。因此,下面的行 "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库源代码链接为(与Epeli相同)https://github.com/joyent/node/blob/e8067cb68563e3f3ab760e3ce8d0aeb873198f36/lib/http.js#L889


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