Bailey Parker
Bailey Parker

Reputation: 15905

Watch for connection termination on incoming HTTP requests - Node.JS

When making requests in Node.JS to another HTTP server, you can listen for when the server closes the connection with request.on('close', function(){});. I've been searching for similar functionality within Node's http.createServer(). I assumed that that request variable passed in to the callback had an on() function which I could call to listen for when the client closes the connection.

var http = require('http');
http.createServer(function(req, res) {
    req.on('close', function() { console.log("Connection closed"); });
}).listen(80, '127.0.0.1');

However, after reading the 0.4.9 docs on streams, I noticed that under the close event it said:

Not all streams will emit this. (For example, an incoming HTTP request will not emit 'close'.)

Is there a way to listen for client connection terminations from the server in Node?

Upvotes: 2

Views: 2978

Answers (2)

Alfred
Alfred

Reputation: 61773

Socket.io

When you want to know if a socket has closed, which only makes sense when you are do a hanging requests(real-time) I advice you to use socket.io instead, which takes care of all this:

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  io.sockets.emit('this', { will: 'be received by everyone');

  socket.on('private message', function (from, msg) {
    console.log('I received a private message by ', from, ' saying ', msg);
  });

  socket.on('disconnect', function () {
    sockets.emit('user disconnected');
  });
});

The nice thing about socket.io is that it's support by every browser(major) without you having to worry about the little details(which make you go insane). They have abstracted that with a nice API.

Express:

Or when using Express

var app = require('express').createServer();

app.get('/', function(req, res){
    req.on('close', function () {
        console.log('closed');
    });
});

app.listen(3000, '127.0.0.1');

Upvotes: 2

chjj
chjj

Reputation: 14602

Well, you could access the socket directly by doing:

req.socket.on('close', ...);

However, doing this inside a request listener will bind the event for every request. So instead you should bind to the connection event:

var server = http.createServer();
server.on('request', function(req, res) { ... });
server.on('connection', function(socket) {
  socket.on('close', function() {
    console.log(socket.remoteAddress + '\'s keep-alive session died!');
  });
});

EDIT: Maybe I should have mentioned, yes, technically the socket object for an http server will carry a reference to the response on the _httpMessage property. However, I would advise against using this as it is part of the internal API and is subject to change without any warning.

It would be better to add your own property to get a reference to the last request made:

server.on('request', function(req, res) {
  req.socket.currentRequest = req;
});
server.on('connection', function(socket) {
  socket.on('close', function() {
    var req = socket.currentRequest;
    console.log('Socket closed. Last request for: ' + req.url);
  });
});

Upvotes: 7

Related Questions