http - 在 Node.js HTTP 服务器上重用 TCP 连接

标签 http node.js proxy keep-alive

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

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

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

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

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

Emitted exactly once for each request. After that, no more 'data' events will be emitted on the request.

好的,我不能使用那个请求。但是有什么方法可以处理同一个 TCP 连接并在其上创建新请求吗?

背景:我正在研究代理实现。如果用户访问使用 NTLM 的网站我必须坚持一个连接,以使至少该类型的身份验证所需的三个客户端请求不会遇到 this。问题。

你知道我可以尝试什么吗?

提前致谢!

最佳答案

当我使用 Node v6.17 运行此代码时,它提示 keep alive 不起作用

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('结束', 函数() {

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

关于http - 在 Node.js HTTP 服务器上重用 TCP 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10247865/

相关文章:

php - 如何处理通过 POST 发送的 XML?

javascript - 使用分块传输通过 HTTP POST 流式传输麦克风输出

javascript - 快速 js 路由上的传递函数不起作用

ruby - 使用 body_stream 和参数发布请求

node.js - 错误! Windows_NT 6.3.9600,windows8无法安装cordova

java - jetty 服务器 : keep alive timeout for HTTP connection

php - nginx 中的 lumen http 错误 500 以及如何查看 error_log?

javascript - 如何从index.html获取我的js文件的所有src?

node.js - Node/Express良好的错误处理方法?

JavaScript - 代理集与 defineProperty