Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am using a http.Serverobject of the default http module (-> API).

If a client connects the request event is emmited by the server and a http.ServerRequestobject is passed to the event handler. That request object emits the following three events:

  • data (incoming data)
  • end (request ended)
  • close (connection closed)

I want to keep the initial (TCP) connection of the client and reuse it for several requests. The client supports this behaviour as it sends the "Connection: keep-alive" header.

But how do I realize this using node.js? My problem is that after the first request the end event is emitted, and just like the official API says about that event:

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

OK, I can't use that request. But is there any way to work on the same TCP connection and create a new request on it?

Background: I am working on a proxy implementation. If the user accesses a website that uses NTLM I have to stick to one connection for at least the three client requests that are required for that type of authentication to not run into this problem.

Do you have any idea what I might try?

Thanks in advance!

share|improve this question
    
AFAIK Node.js uses Agents for connection reuse. I think you should check out the http lib source from here github.com/joyent/node/blob/… –  Epeli Apr 20 '12 at 17:43
    
Agents are only used for client requests, and I need this behaviour on the server side. Nevertheless you're right that an Agent is responsible for closing outgoing connections. –  muffel Apr 20 '12 at 18:35
add comment

1 Answer

When I run this code with node v6.17 it suggests keep alive is not working

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();
}

IT only worked when I added an exclamation mark to line 1263 of the http lib source that Epeli helpfully supplied. Thus the line below that reads "if (req.shouldKeepAlive){" should instead read "if (! req.shouldKeepALive){" res.on('end', function() {

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

This line is within the on 'end' callback that is set within the ClientRequest.prototype.onSocket closure that starts on line 1113.

The link to this http lib source is (the same as Epeli's) https://github.com/joyent/node/blob/e8067cb68563e3f3ab760e3ce8d0aeb873198f36/lib/http.js#L889

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.