How to check if connection was aborted in node.js server - node.js

I'm making some long polling with node.js.
Basically, node.js server accepts request from the user and then checks for some updates. If there're no updates, it will check them after the timeout.
But what if user has closed his tab, or went to another page? In my case, the script continues working.
Is there a way in node.js to check or detect or to catch an event when user has aborted his request (closed the connection)?

You need to use req.on('close', function(err) { ... }); instead of req.connection.on('close', function(err) { ... });
There is a very important distinction. req.on() adds a listener to this request while req.connection.on(), you add a listener to the (keep-alive) connection between the client and the server. If you use req.connection.on(), every time the client re-uses a connection, you add one more listener to the same connection. When the connection is finally aborted, all listeners are fired.
Function scoping typically keeps you safe from this screwing up your server logic, but it's a dangerous thing nevertheless. Fortunately at least NodeJS 0.10.26 is smart enough to warn the user of this:
(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace:
at Socket.EventEmitter.addListener (events.js:160:15)
at Socket.Readable.on (_stream_readable.js:689:33)
...

Thanks to Miroshko's and yojimbo87's answers I was able to catch the 'close' event, but I had to make some additional tweaks.
The reason why just catching 'close' event wasn't fixing my problem, is that when client sends the request to the node.js server, the server itself can't get information if the connection is still open until he sends something back to the client (as far as I understood - this is because of the HTTP protocol).
So, the additional tweak was to write something to the response from time to time.
One more thing that was preventing this to work, is that I had 'Content-type' as 'application/json'. Changing it to 'text/javascript' helped to stream 'white spaces' from time to time without closing the connection.
In the end, I had something like this:
var server = http.createServer(function(req,res){
res.writeHead(200, {'Content-type': 'text/javascript'});
req.connection.on('close',function(){
// code to handle connection abort
});
/**
* Here goes some long polling handler
* that performs res.write(' '); from time to time
*/
// some another code...
});
server.listen(NODE_PORT, NODE_LISTEN_HOST);
My original code is much bigger, so I had to cut it a lot just to show the sensitive parts.
I'd like to know if there are better solutions, but this is working for me at the moment.

Is there a way in node.js to check or detect or to catch an event when
user has aborted his request (closed the connection)?
You can try to use http.ServerRequest close event. Simple example:
var http = require("http"),
util = require("util");
var httpServer = http.createServer(function(req, res) {
util.log("new request...");
// notify me when client connection is lost
req.on("close", function(err) {
util.log("request closed...");
});
// wait with response for 15 seconds
setTimeout(function() {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write("response");
res.end();
util.log("response sent...");
}, 15000);
});
httpServer.listen(8080);
util.log("Running on 8080");

I'm using Express.js (~4.10.6) and the following code is working fine for me:
//GET Request:
app.get('/', function(req, res){
req.on('close', function(){
console.log('Client closed the connection');
});
});
As soon as I close the browser's tab, the browser closes the connection, and the callback function gets executed as expected.

Seems that your question is very similar to this one:
NodeJS HTTP request connection's close event fired twice
try
request.connection.on('close', function () {
...
});

Related

Wait for socket connection to establish (when changing page path), till sending router data to the user

I need the socket connection to establish before I can send data from the route to the user (otherwise it is not possible).
In app.js file I have socket connection logic:
app.use(function(req, res, next)
{
req.sio = sio;
next();
});
sio.on('connection',
function(soc)
{
console.log('socket connected');
soc.on('disconnect', function(reason)
{
console.log('socket disconnected');
});
// and more about socket connection here...
});
In index.js file I have route.post logic:
router.post('/route1', function(req, res, next) // user is moved from index.js to route1.js if he fills the form
{
var fromInput = req.body.form_name;
console.log('DATA passed from INDEX.JS: ' + formInput);
if ((formInput !== '') && (formInput !== null) && (formInput !== undefined))
{
function render()
{
//// first we render the page, so the javascript (with socket.io notes) can be read it and then the browser know that socket connection should be established
return new Promise(function(resolve, reject)
{
resolve(res.render('route1'));
});
}
// I need to pass some data AFTER the socked connection is established - cause I move to a different page path - using a **router.post** and cause of that socket connection is disconnected - so I need to wait till its usable again. For simplicity let suppose socket connection is established after 2 seconds (it is a simple check for req.soc.connected):
var soc = false;
setTimeout(function()
{
soc = true; // after 2 sec soc is true (connection is established)
}, 2000);
// Now I want to create an interval that will monitor IF socket connection is established every 100ms (so checking won't happen to often - it is not "resource hungry"). If socket connection is not ready the function should call it self (recursion) if the socket connection is established it (function) should fire a promise.
var arr = [];
arr.push(exe(100, data));
function exe(delay, d)
{
d = data;
return new Promise(function(resolve)
{
if (d === false)
{
setTimeout(function()
{
console.log('wait another ' + delay + ' [ms] - ' + d);
return resolve(exe(delay, d));
}, delay);
}
else
{
console.log('socket connected!');
return resolve(d);
}
});
}
render().then(function()
{
return Promise.all(arr).then(function(arr)
{
console.log(arr);
});
}).then(function()
{
console.log('ALL DONE!');
});
}
});
Comment are in code. If something isn't clear let me know.
#jfriend00
1 - true,
2 - true,
3 - I call render() immediately - so page is loaded and client make a socket connection, then the rest of the code should execute and send the data.
yes I did use POST with a form. There could be socket connection between the server and index page - not a problem I can create one, but I dunno what for.
"or there could be a socket.io connection created in the response to the POST when the browser renders and processes that." I'm trying that one :) I have data in this router.post I want to sent with help of sockets - but first I need to make a connection.
as I understand it... user did use form, so path is changed (socket connection is broken), then I'm in router.post I render the page FIRST - so the browser can read it's JS and make a socket connection, BUT you want to say that my response is not finished? So the browser say - ok you want me to render a page, but what now - cause we are NOT finish yet?!
So I will never establish a socket connection, cause I did not properly response? And cause of this I will not be able to send the data (later code in router.post) cause socket connection is never established cause I did not response properly? Cause my tests show me otherwise - it is working just fine.
you are right - code should works now.
till socket connection is established.
yea, good catch. I will make some kind of database - redis with express session I guess.
So again step by step.
User did fill the form so he is redirect from index.js to route1.js (so it does not make a difference if there is a socket connection BEFORE filling the form or not cause the connection is lost). We are in process of redirecting him (router.post) so I thought I will render the route1 page immediately, so the JS from it can be read by browser, and socket connection can be established (which take time - and IF its possible). So I wait with the data I want to sent to the user (in router.post for example... the form input or whatever) TILL the connection is established, and the send it to the user, with help of socket.io.
The thing is that socket io connection is lost when you change page (path). So I thought (and it could be wrong cause I'm newb) then I wait till it is established, and then send the data. I hope it does make sense.
This structure can never work. Here's what it looks like you're trying to do:
Express server receives a POST request.
Then, you try to wait for a socket.io connection to appear before you process the POST and send a response.
Finally, when you think you've found a socket.io connection, you then call your render() function to "presumably" send a response.
Without really understanding what you're' trying to accompilsh, there are a number of things wrong with the current code:
A POST request comes from either an Ajax call or a form POST. There is no socket.io connection associated directly with either one of those. There could have been a socket.io connection when the page loaded BEFORE the POST request was sent or there could be a socket.io connection created in the response to the POST when the browser renders and processes that.
Even if there was a socket.io connection created when the browser processes the POST response, you're trying to wait for the socket.io connection BEFORE you send the response so you're waiting for something that won't happen until you're done waiting (essentially a deadlock - A won't finish until B finishes, but B can't start until A finishes).
This structure render().then(waitUntil(100, d)) isn't correct. You MUST pass .then() a function reference. You are passing it a promise (the return value form calling waitUntil(...)). This is the least of your problems though because the overall structure of what you're trying to do is wrong.
The whole implementation of waitUntil() is confused and I can't even tell what it's trying to actually wait for.
This is a server that can field lots of connections from lots of clients. You can't just wait for the "next" socket.io connection and assume that connection is from the client you just got a request for. The only way to associate a socket.io connection with an http request is to use some identifying characteristic in both (usually a cookie) and then in the http request, you get the cookie and look up the cookie to see if you currently have a socket.io connection that matches that cookie. This is something that express-socket.io-session helps with.
Unfortunately, you don't describe what you're really trying to accomplish here so I can't point you to a good solution. All, I can really say here is that this scheme will not work. If you want further help with the actual problem, please edit your question to include the problem description in words (not your coding issues). Show the exact sequence of events you want to happen and explain what you're trying to accomplish and why.

Node.js server.close() won't close due to active connection

I'm trying to show some information before the application is closed. So, I create an event that will be fired when the server receive a SIGINT. This code will work if no connection is ever made. However, if there had been a connection localhost:4040, the server will never close as the server think there is still an active connection(connection count will be 1). The part I don't understand is why Node.js still think there is an active connection when the request has already finish. Is there any ways to kill a connection or my current way of closing the request is wrong?
Here is the code of What I'm trying to accomplish:
var http = require('http')
var server = http.createServer(function(req, res){
res.end('test');
}).listen(4040);
process.on( 'SIGINT', function(){
server.getConnections(function(err, count){
console.log('connection:' + count);
})
server.close(function(){
process.exit();
});
})
Some ideas I have:
saving a copy of the sockets I receive and close them individually
Hope someone can give me some advice in solving this.Thanks
store all sockets from you have and close them manually
use process.exit() and destroy the entire process instead
use domains and do a scary deprecated domain.dispose()

NodeJS - What does "socket hang up" actually mean?

I'm building a web scraper with Node and Cheerio, and for a certain website I'm getting the following error (it only happens on this one website, no others that I try to scrape.
It happens at a different location every time, so sometimes it's url x that throws the error, other times url x is fine and it's a different url entirely:
Error!: Error: socket hang up using [insert random URL, it's different every time]
Error: socket hang up
at createHangUpError (http.js:1445:15)
at Socket.socketOnEnd [as onend] (http.js:1541:23)
at Socket.g (events.js:175:14)
at Socket.EventEmitter.emit (events.js:117:20)
at _stream_readable.js:910:16
at process._tickCallback (node.js:415:13)
This is very tricky to debug, I don't really know where to start. To begin, what IS a socket hang up error? Is it a 404 error or similar? Or does it just mean that the server refused a connection?
I can't find an explanation of this anywhere!
EDIT: Here's a sample of code that is (sometimes) returning errors:
function scrapeNexts(url, oncomplete) {
request(url, function(err, resp, body) {
if (err) {
console.log("Uh-oh, ScrapeNexts Error!: " + err + " using " + url);
errors.nexts.push(url);
}
$ = cheerio.load(body);
// do stuff with the '$' cheerio content here
});
}
There is no direct call to close the connection, but I'm using Node Request which (as far as I can tell) uses http.get so this is not required, correct me if I'm wrong!
EDIT 2: Here's an actual, in-use bit of code that is causing errors. prodURL and other variables are mostly jquery selectors that are defined earlier. This uses the async library for Node.
function scrapeNexts(url, oncomplete) {
request(url, function (err, resp, body) {
if (err) {
console.log("Uh-oh, ScrapeNexts Error!: " + err + " using " + url);
errors.nexts.push(url);
}
async.series([
function (callback) {
$ = cheerio.load(body);
callback();
},
function (callback) {
$(prodURL).each(function () {
var theHref = $(this).attr('href');
urls.push(baseURL + theHref);
});
var next = $(next_select).first().attr('href');
oncomplete(next);
}
]);
});
}
There are two cases when socket hang up gets thrown:
When you are a client
When you, as a client, send a request to a remote server, and receive no timely response. Your socket is ended which throws this error. You should catch this error and decide how to handle it: whether retry the request, queue it for later, etc.
When you are a server/proxy
When you, as a server, perhaps a proxy server, receive a request from a client, then start acting upon it (or relay the request to the upstream server), and before you have prepared the response, the client decides to cancel/abort the request.
This stack trace shows what happens when a client cancels the request.
Trace: { [Error: socket hang up] code: 'ECONNRESET' }
at ClientRequest.proxyError (your_server_code_error_handler.js:137:15)
at ClientRequest.emit (events.js:117:20)
at Socket.socketCloseListener (http.js:1526:9)
at Socket.emit (events.js:95:17)
at TCP.close (net.js:465:12)
Line http.js:1526:9points to the same socketCloseListener mentioned by #Blender, particularly:
// This socket error fired before we started to
// receive a response. The error needs to
// fire on the request.
req.emit('error', createHangUpError());
...
function createHangUpError() {
var error = new Error('socket hang up');
error.code = 'ECONNRESET';
return error;
}
This is a typical case if the client is a user in the browser. The request to load some resource/page takes long, and users simply refresh the page. Such action causes the previous request to get aborted which on your server side throws this error.
Since this error is caused by the wish of a client, they don't expect to receive any error message. So, no need to consider this error as critical. Just ignore it. This is encouraged by the fact that on such error the res socket that your client listened to is, though still writable, destroyed.
console.log(res.socket.destroyed); //true
So, no point to send anything, except explicitly closing the response object:
res.end();
However, what you should do for sure if you are a proxy server which has already relayed the request to the upstream, is to abort your internal request to the upstream, indicating your lack of interest in the response, which in turn will tell the upstream server to, perhaps, stop an expensive operation.
Take a look at the source:
function socketCloseListener() {
var socket = this;
var parser = socket.parser;
var req = socket._httpMessage;
debug('HTTP socket close');
req.emit('close');
if (req.res && req.res.readable) {
// Socket closed before we emitted 'end' below.
req.res.emit('aborted');
var res = req.res;
res.on('end', function() {
res.emit('close');
});
res.push(null);
} else if (!req.res && !req._hadError) {
// This socket error fired before we started to
// receive a response. The error needs to
// fire on the request.
req.emit('error', createHangUpError());
req._hadError = true;
}
}
The message is emitted when the server never sends a response.
One case worth mentioning: when connecting from Node.js to Node.js using Express, I get "socket hang up" if I don't prefix the requested URL path with "/".
below is a simple example where I got the same error when I missed to add the commented code in below example. Uncommenting the code req.end() will resolve this issue.
var fs = require("fs");
var https = require("https");
var options = {
host: "en.wikipedia.org",
path: "/wiki/George_Washington",
port: 443,
method: "GET"
};
var req = https.request(options, function (res) {
console.log(res.statusCode);
});
// req.end();
I used require('http') to consume https service and it showed "socket hang up".
Then I changed require('http') to require('https') instead, and it is working.
Expanding on Blender's answer, this happens in a number of situations. The most common ones I run into are:
The server crashed.
The server refused your connection, most likely blocked by User-Agent.
socketCloseListener, as outlined in Blender's answer, is not the only place that hangup errors are created.
For example, found here:
function socketOnEnd() {
var socket = this;
var req = this._httpMessage;
var parser = this.parser;
if (!req.res) {
// If we don't have a response then we know that the socket
// ended prematurely and we need to emit an error on the request.
req.emit('error', createHangUpError());
req._hadError = true;
}
if (parser) {
parser.finish();
freeParser(parser, req);
}
socket.destroy();
}
You could try curl with the headers and such that are being sent out from Node and see if you get a response there. If you don't get a response with curl, but you do get a response in your browser, then your User-Agent header is most likely being blocked.
Another case worth mentioning (for Linux and OS X) is that if you use a library like https for performing the requests, or if you pass https://... as a URL of the locally served instance, you will be using port 443 which is a reserved private port and you might be ending up in Socket hang up or ECONNREFUSED errors.
Instead, use port 3000, f.e., and do an http request.
For request module users
Timeouts
There are two main types of timeouts: connection timeouts and read timeouts. A connect timeout occurs if the timeout is hit while your client is attempting to establish a connection to a remote machine (corresponding to the connect() call on the socket). A read timeout occurs any time the server is too slow to send back a part of the response.
Note that connection timeouts emit an ETIMEDOUT error, and read timeouts emit an ECONNRESET error.
This caused me issues, as I was doing everything listed here, but was still getting errors thrown. It turns out that calling req.abort() actually throws an error, with a code of ECONNRESET, so you actually have to catch that in your error handler.
req.on('error', function(err) {
if (err.code === "ECONNRESET") {
console.log("Timeout occurs");
return;
}
//handle normal errors
});
I had the same problem while using Nano library to connect to Couch DB. I tried to fine tune connection pooling with use of keepaliveagent library and it kept failing with socket hang up message.
var KeepAliveAgent = require('agentkeepalive');
var myagent = new KeepAliveAgent({
maxSockets: 10,
maxKeepAliveRequests: 0,
maxKeepAliveTime: 240000
});
nano = new Nano({
url : uri,
requestDefaults : {
agent : myagent
}
});
After some struggling I was able to nail the problem - as it came out it was very, very simple mistake. I was connecting to the database via HTTPS protocol, but I kept passing to my nano object a keepalive agent created as the examples for use of this library show (they rely on some defaults that use http).
One simple change to use HttpsAgent did the trick:
var KeepAliveAgent = require('agentkeepalive').HttpsAgent;
I think "socket hang up" is a fairly general error indicating that the connection has been terminated from the server end. In other words, the sockets being used to maintain the connection between the client and the server have been disconnected. (While I'm sure many of the points mentioned above are helpful to various people, I think this is the more general answer.)
In my case, I was sending a request with a payload in excess of 20K. This was rejected by the server. I verified this by removing text and retrying until the request succeeded. After determining the maximum acceptable length, I verified that adding a single character caused the error to manifest. I also confirmed that the client wasn't the issue by sending the same request from a Python app and from Postman. So anyway, I'm confident that, in my case, the length of the payload was my specific problem.
Once again, the source of the problem is anecdotal. The general problem is "Server Says No".
I had the same problem during request to some server. In my case, setting any value to User-Agent in headers in request options helped me.
const httpRequestOptions = {
hostname: 'site.address.com',
headers: {
'User-Agent': 'Chrome/59.0.3071.115'
}
};
It's not a general case and depends on server settings.
This error also can happen when working with http.request, probably your request is not finished yet.
Example:
const req = https.request(options, res => {})
And you always need to add this line: req.end()
With this function we will order to finish sending request.
As in documentation is said:
With http.request() one must always call req.end() to signify the end of the request - even if there is no data being written to the request body.
Also reason can be because of using app instance of express instead of server from const server = http.createServer(app) while creating server socket .
Wrong
const express = require('express');
const http = require('http');
const WebSocket = require('ws');
const app = express();
app.use(function (req, res) {
res.send({ msg: "hello" });
});
const wss = new WebSocket.Server({ server: app }); // will throw error while connecting from client socket
app.listen(8080, function listening() {
console.log('Listening on %d', server.address().port);
});
Correct
const express = require('express');
const http = require('http');
const WebSocket = require('ws');
const app = express();
app.use(function (req, res) {
res.send({ msg: "hello" });
});
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
server.listen(8080, function listening() {
console.log('Listening on %d', server.address().port);
});
it's been a long time but another case is when performing requests which takes a long time on the server side (more then 2 minutes which is the default for express) and the timeout parameter was not configured in the server side. In my case I was doing client->server->server request (Node.js express) and I should set the timeout parameter on each request router on the server and on the client.
So in both servers I needed to set the request timeout by using
req.setTimeout([your needed timeout])
on the router.
I do both web (node) and Android development, and open Android Studio device simulator and docker together, both of them use port 8601, it complained socket hang up error, after close Android Studio device simulator and it works well in node side. Don’t use Android Studio device simulator and docker together.
There seems to be one additional case here, which is Electron not being a fan of the "localhost" domain name. In my case I needed to change this:
const backendApiHostUrl = "http://localhost:3000";
to this:
const backendApiHostUrl = "http://127.0.0.1:3000";
After that the problem just went away.
This means that DNS resolution (local or remote) might be causing some problems too.
I got a similar error when using CouchDB on OCP cluster.
const cloudantSessionStore = sessionStore.createSessionStore(
{
type: 'couchdb',
host: 'https://' + credentials['host'],
port: credentials['port'],
dbName: 'sessions',
options: {
auth: {
username: credentials['username'],
password: credentials['password']
},
cache: false
}
}
Which should be "http", not "https", to connect with my CouchDB instance. Hope it could be helpful for anyone who is faced with similar issue.
In my case, it was because a application/json response was badly formatted (contains a stack trace). The response was never send to the server.
That was very tricky to debug because, there were no log. This thread helps me a lot to understand what happens.
In case you're using node-http-proxy, please be aware to this issue, which will result a socket hang-up error : https://github.com/nodejitsu/node-http-proxy/issues/180.
For resolution, also in this link, simply move declaring the API route (for proxying) within express routes before express.bodyParser().
Ran into this issue yesterday running my web application and node.js server through IntelliJ IDEA 2016.3.6. All I had to do was clear my cookies and cache in my Chrome browser.
If you are experiencing this error over a https connection and it's happening instantly it could be a problem setting up the SSL connection.
For me it was this issue https://github.com/nodejs/node/issues/9845 but for you it could be something else. If it is a problem with the ssl then you should be able to reproduce it with the nodejs tls/ssl package just trying to connect to the domain
I think worth noting...
I was creating tests for Google APIs. I was intercepting the request with a makeshift server, then forwarding those to the real api. I was attempting to just pass along the headers in the request, but a few headers were causing a problem with express on the other end.
Namely, I had to delete connection, accept, and content-length headers before using the request module to forward along.
let headers = Object.assign({}, req.headers);
delete headers['connection']
delete headers['accept']
delete headers['content-length']
res.end() // We don't need the incoming connection anymore
request({
method: 'post',
body: req.body,
headers: headers,
json: true,
url: `http://myapi/${req.url}`
}, (err, _res, body)=>{
if(err) return done(err);
// Test my api response here as if Google sent it.
})
I my case it's was not an error, but expected behavior for chrome browser. Chrome keeps tls connection alive (for speed i think), but node.js server stop it after 2 min and you get an error.
If you try GET request using edge browser, there will be no error at all.
If you will close chrome window - you will get error right away.
So what to do?
1)You can filter this errors, because they are not really errors.
2)Maybe there is a better solution :)
After a long debug into node js code, mongodb connection string, checking CORS etc, For me just switching to a different port number server.listen(port); made it work, into postman, try that too. No changes to proxy settings just the defaults.
I was using nano, and it took me a long time to figure out this error. My problem was I was using the wrong port. I had port 5948 instead of 5984.
var nano = require('nano')('http://localhost:5984');
var db = nano.use('address');
var app = express();
Might be your server or Socket connection crashes unexpectedly.
I had this error when running two applications on the same port by mistake.
I had a next.js app and another one in nest.js, running both on port 8080, when I looked at the .env files I realized that they had the same port, so I changed the one from nest.js to 3000 and everything worked.
I'm not saying that this is the reason for the error but it's a possibility.
Your problem might also come from an attempt to connect to an HTTP URL while your service is only published on HTTPS...
Definitely a time-consuming mistake!
Got "[GET] localhost:4200, Socket hang up" during Azure Static Web App (SWA) Emulator for Angular app.
Solution is to remove this from angular.json:
"headers": {"cross-origin-opener-policy": "same-origin-allow-popups"}

Node.js Outgoing Http request connection limit (cannot make connections more than five)

I'm building a data transfer proxy server using node.js.
It pipes client's request to swift object storage server using http(s) REST API.
It works fine for the individual request but when the outgoing
ESTABLISHED tcp connection for the same destination and port(443)
reaches five, it cannot create any new connection.
It does not seem to be a problem of O/S, because I've tried to create more than 10 connections using java servlet and it works fine.
I've tried to set maximum sockets for globalAgent like below, but it does not change anything.
http.globalAgent.maxSockets = 500;
https.globalAgent.maxSockets = 500;
Here is a part of my source code.
app.post('/download*', function(req, res){
/***********************************************************
* Some codes here to create new request option
***********************************************************/
var client = https.request(reqOptions, function(swiftRes) {
var buffers = [];
res.header('Content-Length', swiftRes.headers['content-length']);
res.header('Content-Type', swiftRes.headers['content-type']);
res.header('range', swiftRes.headers['range']);
res.header('connection', swiftRes.headers['connection']);
swiftRes.pipe(res);
swiftRes.on('end', function(err){
res.end();
});
});
client.on('error', function(err) {
callback && callback(err);
client.end(err);
clog.error('######### Swift Client Error event occurred. Process EXIT ');
});
client.end();
});
I hope I can get the solution for this problem.
Thanks in advance.
Usually, the change of the maxSockets should solve your problem, try it with a value a little bit lower.
https.globalAgent.maxSockets=20;
If that does not solve your problem, try to turn off pooling for the connections. Add the key agent with the value false to the options to the request. Keep in mind that Node.js uses the pooling to use keep-alive connection.
//Your option code
reqOptions.agent=false;

Detecting close of client connect in node.js

I am using node.js for long held connections. I want to know how I can detect when the client connection closes (maybe when the user closes the tab). How do I specify a callback for that?
Answering my own question - You can detect close of client connection by doing:
http.createServer(function(request, response) {
request.connection.addListener('close', function () {
// callback is fired when connection closed (e.g. closing the browser)
});
}
Take a look at Socket.io. It supports the following transports with fallbacks in this order:
WebSocket
Adobe Flash Socket
AJAX long polling
AJAX multipart streaming
Forever Iframe
JSONP Polling
The benefit is you'll be able to handle a lot more concurrent connections than long polling alone. In addition you'll get a rich set of features like heartbeats and disconnects.
io.sockets.on('connection', function (socket) {
// ... other socket handlers here ...
socket.on('disconnect', function () {
// do something to handle the disconnect
});
});

Resources