节点js ECONNRESET

我运行一个Express js应用程序与socket.io为一个聊天的Web应用程序,我得到了以下错误在24小时内大约5次随机。 节点进程被永久封装,并立即重新启动。

问题是,重新启动快速将我的用户踢出他们的房间,没有人愿意。

Web服务器由HAProxy代理。 没有套接字稳定性问题,只使用websocket和flashsockets传输。 我无法重现这个故意。

这是节点v0.10.11的错误:

events.js:72 throw er; // Unhandled 'error' event ^ Error: read ECONNRESET //alternatively it sa 'write' at errnoException (net.js:900:11) at TCP.onread (net.js:555:19) error: Forever detected script exited with code: 8 error: Forever restarting script for 2 time 

编辑(2013-07-22)

添加了socket.io客户端error handling程序和未捕获的exception处理程序。 似乎这个错误发生了:

 process.on('uncaughtException', function (err) { console.error(err.stack); console.log("Node NOT Exiting..."); }); 

所以我怀疑这不是一个socket.io问题,而是一个http请求到另一个服务器,我做的或者一个mysql / redis连接。 问题是,错误堆栈不能帮助我识别我的代码问题。 这里是日志输出:

 Error: read ECONNRESET at errnoException (net.js:900:11) at TCP.onread (net.js:555:19) 

我怎么知道是什么原因造成的? 我如何从错误中获得更多的信息?

好吧,不是很详细,但这里是“longjohn”的堆栈跟踪:

 Exception caught: Error ECONNRESET { [Error: read ECONNRESET] code: 'ECONNRESET', errno: 'ECONNRESET', syscall: 'read', __cached_trace__: [ { receiver: [Object], fun: [Function: errnoException], pos: 22930 }, { receiver: [Object], fun: [Function: onread], pos: 14545 }, {}, { receiver: [Object], fun: [Function: fireErrorCallbacks], pos: 11672 }, { receiver: [Object], fun: [Function], pos: 12329 }, { receiver: [Object], fun: [Function: onread], pos: 14536 } ], __previous__: { [Error] id: 1061835, location: 'fireErrorCallbacks (net.js:439)', __location__: 'process.nextTick', __previous__: null, __trace_count__: 1, __cached_trace__: [ [Object], [Object], [Object] ] } } 

在这里,我服务于闪存套接字策略文件:

 net = require("net") net.createServer( (socket) => socket.write("<?xml version=\"1.0\"?>\n") socket.write("<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n") socket.write("<cross-domain-policy>\n") socket.write("<allow-access-from domain=\"*\" to-ports=\"*\"/>\n") socket.write("</cross-domain-policy>\n") socket.end() ).listen(843) 

这可能是原因吗?

你可能已经猜到了:这是一个连接错误。

“ECONNRESET”意味着TCP对话的另一端突然closures了连接的结束。 这很可能是由于一个或多个应用程序协议错误。 你可以看看API服务器日志,看看是否有抱怨。

但是既然你也在寻找一种方法来检查错误并且可能debugging问题,那么你应该看看“ 如何在NodeJS中debugging套接字挂起错误?

快速和肮脏的发展解决scheme

使用longjohn ,会得到包含asynchronous操作的长堆栈跟踪。

清理和正确的解决scheme :从技术上讲,在节点中,每当你发出一个'error'事件,而没有人听,它就会抛出 。 为了让它不扔,把一个听众,并自己处理。 这样你可以logging更多的信息的错误。

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

编辑(2013-07-22)

正如我上面写的:

“ECONNRESET”意味着TCP对话的另一端突然closures了连接的结束。 这很可能是由于一个或多个应用程序协议错误。 你可以看看API服务器日志,看看是否有抱怨。

也可能是这样的:在随机的时候,另一方被超载,并简单地杀死连接。 如果是这样的话,取决于你正在连接到什么…

但有一件事是肯定的:你的TCP连接确实有一个读错误,导致exception。 您可以通过查看您在编辑中发布的错误代码来确认。

我有一个简单的tcp服务器用于提供Flash策略文件, 我现在可以使用处理程序捕获错误:

 # serving the flash policy file net = require("net") net.createServer((socket) => //just added socket.on("error", (err) => console.log("Caught flash policy server socket error: ") console.log(err.stack) ) socket.write("<?xml version=\"1.0\"?>\n") socket.write("<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n") socket.write("<cross-domain-policy>\n") socket.write("<allow-access-from domain=\"*\" to-ports=\"*\"/>\n") socket.write("</cross-domain-policy>\n") socket.end() ).listen(843) 

我有一个类似的问题,应用程序在升级Node后出现错误。 我相信这可以追溯到Node release v0.9.10这个项目:

  • 网:不要压制ECONNRESET(Ben Noordhuis)

以前的版本不会因客户端的中断而出错。 来自客户端的连接中断会引发节点中的ECONNRESET错误。 我相信这是Node的function,所以修复(至less对我来说)是处理错误,我相信你在未捕获的exception中所做的。 虽然我在net.socket处理程序中处理它。

你可以certificate这一点:

做一个简单的套接字服务器,并得到节点v0.9.9和v0.9.10。

 require('net') .createServer( function(socket) { // no nothing }) .listen(21, function() { console.log('Socket ON') }) 

使用v0.9.9启动它,然后尝试FTP到这个服务器。 我只使用FTP和端口21,因为我在Windows上,有一个FTP客户端,但没有telnet客户端方便。

然后从客户端,只是断开连接。 (我只是在做Ctrl-C)

使用Node v0.9.9时应该看到NO ERROR,使用Node v.0.9.10和更高版本时应该看到ERROR。

在生产中,我使用v.0.10。 东西,它仍然给出了错误。 再次,我认为这是意图和解决scheme是处理您的代码中的错误。

我面临同样的问题,但我通过下列方式减轻了这个问题:

 server.timeout = 0; 

server.listen之前。 服务器在这里是一个HTTP服务器。 根据API文档 ,默认的超时时间为2分钟。

今天有同样的问题。 经过一番研究,我发现了一个非常有用的--abort-on-uncaught-exception node.js选项 。 它不仅提供了更详细和有用的错误堆栈跟踪,而且还保存了核心文件在应用程序崩溃允许进一步debugging。

是的,您提供的政策文件肯定会导致崩溃。

重复一下,只需在代码中添加延迟:

 net.createServer( function(socket) { for(i=0; i<1000000000; i++); socket.write("<?xml version=\"1.0\"?>\n") … 

…并使用telnet连接到端口。 如果在延迟过期之前断开远程login,当socket.write引发错误时,将会发生崩溃(未捕获的exception)。

为了避免这里的崩溃,只需在读/写套接字之前添加一个error handling程序:

 net.createServer( function(socket) { for(i=0; i<1000000000; i++); socket.on('error', function() { console.log("error"); }); socket.write("<?xml version=\"1.0\"?>\n") 

当你尝试上面的断开连接,你只会得到一个日志消息,而不是崩溃。

当你完成时,记得要消除延迟。

另一个可能的情况(但很less见)可能是如果你有服务器到服务器通信,并已经设置server.maxConnections到一个非常低的价值。

在节点的核心库net.js中,它会调用clientHandle.close() ,这也会导致错误ECONNRESET:

 if (self.maxConnections && self._connections >= self.maxConnections) { clientHandle.close(); // causes ECONNRESET on the other end return; }