Nodejs Socket повесить трубку и ECONNRESET - HTTP-запрос от Meteor до Node js server
Я использую сервер node для обработки всех моих служб push-уведомлений, таких как gcm и apn.
У меня есть 2 разных сервера. Один запускает Meteor, а другой работает Node.JS для обработки push-уведомлений. (Оба являются разными серверами)
Мое главное приложение работает на сервере Meteor.
Я отправляю HTTP-запрос на сервер Node.js для отправки уведомлений.
Обычно он работает нормально, но иногда на сервере Meteor я получаю эту ошибку всякий раз, когда я вызываю сервер Node.js:
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] }
ИЛИ
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)
Вот мой код сервера Node.JS:
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);
});
И вот мой код со стороны Метеор, где я делаю HTTP-запрос на сервер node js:
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 });
Может ли кто-нибудь вести меня в правильном направлении? Кроме того, я был бы очень признателен за то, что вы также знаете некоторые хорошие практики.
И
Есть еще одна проблема, с которой я столкнулся. Мой сервер Node.js завершает работу через 24 часа. Я не знаю, почему это происходит. Он выходит без каких-либо ошибок или исключений в терминальной консоли. Я должен перезапустить его каждый раз.
Ответы
Ответ 1
Хорошо, я сам нашел эту проблему. Его код сервера node. Я положил return в оператор switch, который не является допустимым способом для возврата ответа в выражении, поэтому я просто удалил возврат из:
До:
switch (callType) {
case 'systemPushNotifications':
return pushNotificationClass.sendPushNotificationsV2(response);
break;
}
Теперь:
switch (callType) {
case 'systemPushNotifications':
pushNotificationClass.sendPushNotificationsV2(response);
break;
}
Вышеупомянутый return
завершал код перед: res.send("OK");
Ответ 2
Учитывая, что ошибка ECONNRESET обычно возникает, когда * другая сторона TCP connection
закрыта внезапно.
- В случае вашей заявки
это может быть связано с
overloading
сервера и просто убивает соединение в качестве возврата, которое аналогичным образом блокирует соединение с вашим meteor server
Чтобы получить дополнительную информацию об ошибке, упомянутой в этом потоке.
Чтобы обработать ошибку, вы должны использовать event listener
для отображения полного stack traces
этого
Как упоминалось в этой теме Farid Nouri Neshat
Чтобы иметь одного слушателя для группы вызовов, вы можете использовать домены, а также улавливать другие ошибки во время выполнения. Убедитесь, что каждая операция async, связанная с http (Server/Client), находится в другом контексте domain по сравнению с другими частями кода, домен будет автоматически прослушивать события ошибки и будет распространять его на свой собственный обработчик. Поэтому вы только слушаете этого обработчика и получаете данные об ошибках.
но поскольку домен уже устарел, вы должны использовать кластеры, как указано здесь, в docs, который использует server.listen(message)
и server.listen(handle)
или вы также можете использовать NODE_DEBUG=net
или использовать strace
Обновление
Для отключения сервера я думаю, что ошибка может заключаться в обработке bodyparser
. Для плохого файла json
ошибка не показана.
Node действие по умолчанию после неперехваченного исключения - это exit (crash) в процессе.
Обработка bodyparser для json файла может быть выполнена следующим образом.
var parseJson = bodyPaser.json();
app.use(function (req, res, next) {
req.getBody = function (callback) {
parseJson(req, res,function (err) {
callback(err, req.body);
});
};
next();
});
Ссылка, взятая из открытой проблемы GITHUB здесь
Обновление 2
В основном socket hangup
означает, что сокет не завершает соединение в течение указанного периода времени
В соответствии с source вы можете видеть, что это происходит, если сервер никогда не отправляет ответ
.Эту ошибку следует поймать и обработать с помощью
- Повторить запрос.
- обработать его позже, установив больше
time period
или поместив res.end()
в конец вашей функции, чтобы завершить соединение.
- или вы можете использовать
[http.get()][8]
с запросами get
, которые автоматически вызовут функцию req.end()
Надеюсь, это поможет вам немного! Ура!