2

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?

2 Answers 2

7

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);
  });
});
Sign up to request clarification or add additional context in comments.

1 Comment

If I was to bind directly to the socket or bind to it from the request, I assume the socket wouldn't carry any identification that would allow me to identify which request it is associated with, correct? I'm trying to code a pseudo media server here, so I need to know when clients close a connection so I don't waste time, and possibly buffer memory, on writing to a closed socket. However, I'm not sure if the callback for a request will even persist if the connection closes. Do you know if closing out a request will stop the callback for that request?
2

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');

3 Comments

Socket.IO certainly removes the headache from both end of live browser-to-server communication, but in this application won't work because I am attempting to feed media files to the browser for an HTML5 video tag. Nonetheless, without this context, Socket.IO would be a great alternative to node's built-in http features.
I did not know that. Have you searched for open-source alternatives to do that?
Good catch. I'll check out express on github to see how they do it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.