在 Node.js HTTP 服务器上重用 TCP 连接
Posted
技术标签:
【中文标题】在 Node.js HTTP 服务器上重用 TCP 连接【英文标题】:Reusing TCP connection on Node.js HTTP Server 【发布时间】:2012-05-02 03:15:19 【问题描述】:我正在使用默认 http
模块 (-> API) 的 http.Server
object。
如果客户端连接了request
事件,服务器会发出一个http.ServerRequest
object 传递给事件处理程序。该请求对象发出以下三个事件:
我想保留客户端的初始 (TCP) 连接并将其重用于多个请求。客户端在发送“Connection: keep-alive”标头时支持此行为。
但是我如何使用 node.js 实现这一点?我的问题是,在第一次请求之后发出 end 事件,就像官方 API 所说的那样:
每个请求只发送一次。在那之后,没有更多的“数据” 将根据请求发出事件。
好的,我不能使用那个请求。但是有什么方法可以在同一个 TCP 连接上工作并在其上创建新请求?
背景:我正在研究代理实现。如果用户访问使用NTLM 的网站,我必须坚持一个连接,以确保该类型身份验证所需的至少三个客户端请求不会遇到this 问题。
你知道我可以尝试什么吗?
提前致谢!
【问题讨论】:
AFAIK Node.js 使用代理进行连接重用。我认为您应该从这里查看 http lib 源代码github.com/joyent/node/blob/… 代理只用于客户端请求,我在服务器端需要这种行为。尽管如此,代理负责关闭传出连接是正确的。 【参考方案1】:当我使用 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('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
【讨论】:
以上是关于在 Node.js HTTP 服务器上重用 TCP 连接的主要内容,如果未能解决你的问题,请参考以下文章