Nodejs套接字挂断&ECONNRESET – 从meteor到Node js服务器的HTTP post请求

我正在使用节点服务器来处理所有的推送通知服务,如gcm和apn。

我有2个不同的服务器。 一个运行Meteor,另一个运行Node.JS来处理推送通知。 (两者都是不同的服务器)

我的主要应用程序在Meteor服务器上运行。

我向node.js服务器发送一个HTTP post请求来发送我的通知。

通常它工作正常,但有时在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] } 

要么

 错误:读取ECONNRESET
     在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 /服务器-LIB / node_modules /纤维/ future.js:398:15)
     在Object.call(packages / meteor / helpers.js:119:1)
     在Object.sendHttpCall(server / pushNotifications.js:249:1)
     在服务器/ pushNotifications.js:244:1
     在[object Object] ._。extend.withValue(packages / meteor / dynamics_nodejs.js:56:1)
     在packages / meteor / timers.js:6:1
     在runWithEnvironment(packages / meteor / dynamics_nodejs.js:110:1)
      -   -   -   -   - 
     在errnoException(net.js:905:11)
     在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); }); 

这里是我从meteor端的代码,在那里我发送HTTP请求到节点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小时之后退出。 我不知道为什么会这样。 它在terminal控制台中没有任何错误或exception退出。 我必须每次重新启动它。

考虑到ECONNRESET错误通常在TCP connection另一侧突然closures时发生。

  • 在你的应用程序的情况下,它可能是由于服务器overloading ,并简单地杀死连接作为返回,类似的方式阻止连接到你的meteor server

要获得更多关于这个线程中提到的错误的信息。 要处理错误,您必须使用event listener来显示它的完整stack traces

正如Farid Nouri Neshat在这个主题中提到的那样

要为一组调用设置一个监听器,您可以使用域并在运行时捕获其他错误。 确保与http(服务器/客户端)相关的每个asynchronous操作与代码的其他部分处于不同的域上下文中,域将自动侦听错误事件并将其传播到它自己的处理程序。 所以你只能听那个处理程序并获取错误数据。

但是由于域已经被弃用,所以你应该使用在这里提到的使用server.listen(message)server.listen(handle)的文档中提到的簇。

或者也可以使用NODE_DEBUG=net或使用strace

更新

对于服务器断开连接,我认为这个错误可能是在您处理bodyparser 。对于一个错误的 json文件错误未被捕获

跟踪未捕获的exception的节点的默认操作是退出(崩溃)的过程。

处理json文件的bodyparser可以通过以下方式完成。

 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意味着套接字不会在指定的时间段内结束连接

根据源,你可以看到, 如果服务器从不发送响应就会发生

这个错误应该被捕获和处理

  • 重试请求。
  • 稍后通过设置更多time period处理它,或者在函数结束处放置res.end()来结束连接。
  • 或者可以使用[http.get()][8]get请求,这些请求将自动调用req.end()函数

希望它可以帮助你一点! 干杯!

好的,我在这里发现了这个问题。 它在节点服务器代码中。 我把返回在一个switch语句中,这不是一个有效的方式来返回一个快速响应,所以我只是删除了返回:

之前:

 switch (callType) { case 'systemPushNotifications': return pushNotificationClass.sendPushNotificationsV2(response); break; } 

现在:

 switch (callType) { case 'systemPushNotifications': pushNotificationClass.sendPushNotificationsV2(response); break; } 

上面的return是终止代码: res.send("OK");