'Nodejs Socket hang up & ECONNRESET - HTTP post request from Meteor to Node js server
I am using a node server to handle all my push notifications services like gcm and apn.
I have 2 different servers. One is running Meteor and another is running Node.JS to handle push notifications. (Both are different servers)
My main app runs on the Meteor server.
I make an HTTP post request to the node.js server to send my notifications.
Usually it works fine, but sometimes on the Meteor server I get this error whenever I call the node.js server:
socket hang up\n at Object.Future.wait (/home/myPc/.meteor/packages/meteor-tool/.1.1.10.ki0ccv++os.linux.x86_64+web.browser+web.cordova/mt-os.linux.x86_64/dev_bundle/server-lib/node_modules/fibers/future.js:398:15)\n at Object.<anonymous> (packages/meteor/helpers.js:119:1)\n at Object.HTTP.call (packages/meteorhacks_kadira/lib/hijack/http.js:10:1)\n at Object.sendPushNotificationsMeteorServer (server/pushNotifications.js:249:1)\n at server/classes/pushNotifications.js:244:1\n at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)\n at packages/meteor/timers.js:6:1\n at runWithEnvironment (packages/meteor/dynamics_nodejs.js:110:1)\n - - - - -\n at createHangUpError (http.js:1473:15)\n at Socket.socketOnEnd [as onend] (http.js:1569:23)\n at Socket.g (events.js:180:16)\n at Socket.emit (events.js:117:20)\n at _stream_readable.js:944:16\n at process._tickCallback (node.js:448:13)',
details: { [Error: socket hang up] stack: [Getter] },
data: { [Error: socket hang up] stack: [Getter] },
user: null,
userId: null,
toString: [Function] },
user: null,
userId: null,
toString: [Function] }
OR
Error: read ECONNRESET at Object.Future.wait (/home/mbm/.meteor/packages/meteor-tool/.1.1.10.12ml1tp++os.linux.x86_64+web.browser+web.cordova/mt-os.linux.x86_64/dev_bundle/server-lib/node_modules/fibers/future.js:398:15) at Object.call (packages/meteor/helpers.js:119:1) at Object.sendHttpCall (server/pushNotifications.js:249:1) at server/pushNotifications.js:244:1 at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1) at packages/meteor/timers.js:6:1 at runWithEnvironment (packages/meteor/dynamics_nodejs.js:110:1) - - - - - at errnoException (net.js:905:11) at TCP.onread (net.js:559:19)
Here is my Node.JS server code:
realFs = require('fs');
var gracefulFs = require('graceful-fs');
gracefulFs.gracefulify(realFs);
var http = require('http');
var express = require('express');
var app = express();
var path = require("path");
configClass = require('./classes/config.js').configClass;
helperClass = require('./classes/helper.js').helperClass;
pushNotificationClass = require('./classes/pushNotification.js').pushNotificationClass;
var hostname = 'http://localhost';
var port = 6000;
var bodyParser = require('body-parser');
nodeGcm = require('node-gcm');
apn = require('apn');
apnService = new apn.Connection(helperClass.getAPNOptions());
// -- BODY PARSER -- //
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
process.on('uncaughtException', function (err) {
console.error(err);
console.log("Node NOT Exiting...");
});
// All post requests
app.post('/', function(req, res){
try {
var response = JSON.parse(req.body.pushNotificationApiParams);
var callType = req.body.callType;
switch (callType) {
case 'systemPushNotifications':
return pushNotificationClass.sendPushNotificationsV2(response);
break;
}
}
catch(e){
console.dir(e.stack);
realFs.appendFile('errorLogs/'+helperClass.getCurrentDateFormated()+'.log', helperClass.formatLog('Exception in main Post Method : '+e.stack) , function (err) {
if (err) throw err;
});
}
res.send("OK");
});
app.listen(port, function () {
console.log('Listening at '+hostname+':'+port);
});
And here is my code from Meteor side, where I am make HTTP post request to node js server:
var headers = {
'Content-Type' : 'application/x-www-form-urlencoded'
};
var postFields = {
callType : 'systemPushNotifications',
pushNotificationApiParams : JSON.stringify(pushNotificationApiParams) // contains push notifications data
};
HTTP.call("POST", 'http://localhost:6000', { params:postFields, headers:headers });
Can anyone guide me in the right direction? Also I would really appreciate to know some good practices as well.
Also
There is one more issue I am facing. My node.js server exits after like 24 hours. I don't know why does that happens. It exits without any error or exception in the terminal console. I have to restart it each time.
Solution 1:[1]
Ok I found the issue myself here. Its in the node server code. I put return in a switch statement which is not a valid way to return a response in express, so I just removed the return from:
Before:
switch (callType) {
case 'systemPushNotifications':
return pushNotificationClass.sendPushNotificationsV2(response);
break;
}
Now:
switch (callType) {
case 'systemPushNotifications':
pushNotificationClass.sendPushNotificationsV2(response);
break;
}
The above return
was terminating the code before the: res.send("OK");
Solution 2:[2]
Considering the ECONNRESET error usually occurs when the *other side of the TCP connection
is closed abruptly.
- In case of your application
it may be due to the
overloading
of the server and simply kills the connection as a return which in the similar way blocks the connection to yourmeteor server
To get more info about the error as mentioned in this thread.
To handle the error you must use an event listener
to it to show the full stack traces
of it
As mentioned in this thread by Farid Nouri Neshat
To have one listener for a group of calls you can use domains and also catch other errors on runtime. Make sure each async operation related to http(Server/Client) is in different domain context comparing to the other parts of the code, the domain will automatically listen to the error events and will propagate it to it's own handler. So you only listen to that handler and get the error data.
but since the domain have already been deprecated you should use clusters as mentioned here in the docs which uses server.listen(message)
and the server.listen(handle)
or you can also use NODE_DEBUG=net
or use strace
Update
For the server disconnect i think the error might be in your handling of the bodyparser
.For a bad json
file the error is uncaught.
Node's default action following an uncaught exception is to exit(crash) on the process.
Handling of bodyparser for a json file can be done in the following way.
var parseJson = bodyPaser.json();
app.use(function (req, res, next) {
req.getBody = function (callback) {
parseJson(req, res,function (err) {
callback(err, req.body);
});
};
next();
});
Reference taken from the GITHUB open issue's here
Update 2
Basically the socket hangup
means that the socket doesn't end the connection within the specified time period
According to the source you can see that it occurs if the server never sends the response
.This error should be caught and handled by either
- retrying to the request.
- handling it later by setting more
time period
or putres.end()
at the end of your function to end the connection. - or you can use the
[http.get()][8]
with theget
requests which will automatically call thereq.end()
function
Hope it might help you a bit! Cheers!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | StormTrooper |
Solution 2 | Community |