我正在通过socket.io运行Express js应用程序进行聊天webapp,我在以下期间大约5次随机收到以下错误24小时节点进程被永久封装,并重新启动本身。
问题是重新启动Express会使我的用户离开他们的房间没有人想要。
Web服务器由HAProxy代理。仅使用websockets和flashsockets传输就没有套接字稳定性问题。我无法有意复制此内容。
这是节点v0.10.11的错误:
events.js:72
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET //alternatively it s a '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
EDIT(2013-07-22)
同时添加了socket.io客户端错误处理程序和未捕获的异常处理程序。似乎这是抓到错误了:
process.on('uncaughtException', function (err) {
console.error(err.stack);
console.log("Node NOT Exiting...");
});
因此,我怀疑这不是socket.io问题,而是对我执行的另一台服务器或mysql / redis连接的http请求。问题是错误堆栈无法帮助我识别代码问题。这是日志输出:
Error: read ECONNRESET
at errnoException (net.js:900:11)
at TCP.onread (net.js:555:19)
我怎么知道是什么原因造成的?我如何从错误中得到更多?
好吧,不是很冗长,但是这里是带有“ longjohn”的stacktrace:
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] ] } }
这里我提供Flash套接字策略文件:
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对话的另一端突然关闭了其连接的末端。这很可能是由于一个或多个应用程序协议错误。您可以查看API服务器日志以查看是否抱怨。
但是由于您还正在寻找一种检查错误并可能调试问题的方法,因此您应该查看一下关于同一个问题的stackoverflow上发布的“ How to debug a socket hang up error in NodeJS?”。
快速而肮脏的开发解决方案:
使用longjohn,您将获得包含异步操作的长堆栈跟踪。
干净且正确的解决方案:从技术上讲,在节点中,每当you emit an
'error'
event and no one listens to it, it will throw。要使其不被抛出,请在其上放置一个侦听器并自己处理。这样,您可以记录错误的更多信息。要在一组呼叫中使用一个侦听器,您可以使用
'error'
,也可以在运行时捕获其他错误。与代码的其他部分相比,确保与http(Server / Client)相关的每个异步操作都在不同的domains上下文中,该域将自动侦听domain事件,并将其传播到它自己的处理程序中。因此,您只听该处理程序并获取错误数据。error
EDIT(2013-07-22)
正如我在上面写的:
“ ECONNRESET”表示TCP对话的另一端突然关闭了其连接的末端。这很可能是由于一个或多个应用程序协议错误。您可以查看API服务器日志以查看是否抱怨。
也可能是这种情况:在随机时间,另一侧过载,结果只是终止了连接。如果是这种情况,请完全取决于您要连接的内容...
但是可以肯定的是:您的TCP连接上确实存在读取错误,这会导致异常。通过查看您在编辑中发布的错误代码可以确认这一点,您可以看到这一点。
我仅通过连接到其他网络就解决了这个问题。这是可能的问题之一。
如上所述,ECONNRESET表示TCP会话突然关闭了其连接的末端。
您的互联网连接可能会阻止您连接到某些服务器。就我而言,我试图连接到mLab(托管MongoDB数据库的云数据库服务)。而且我的ISP阻止了它。
我通过以下方式解决了此问题:
net.createServer( function(socket)
{
for(i=0; i<1000000000; i++);
socket.on('error', function() { console.log("error"); });
socket.write("<?xml version=\"1.0\"?>\n")
更新npm。之后,我尝试了相同的npm命令,但是好了,它解决了。我不确定是否那么简单。
我正在使用CENTOS 7
我有同样的问题,看来是Node.js版本是问题。
我安装了以前版本的Node.js(10.14.2),使用nvm一切正常(允许您安装Node.js的多个版本,并迅速从一个版本切换到另一个版本。
这不是一个“干净”的解决方案,但可以为您提供临时服务。
尝试将这些选项添加到socket.io:
"node server.js"
希望这对您有帮助!
我用于提供Flash策略文件的一个简单的tcp服务器导致了此情况。我现在可以使用处理程序来捕获错误:
You also get more information for free.
我有一个类似的问题,即在升级Node之后,应用程序开始出错。我相信这可以追溯到Node版本v0.9.10的以下项目:
以前的版本不会因客户端中断而出错。来自客户端的连接中断将在节点中引发错误ECONNRESET。我相信这是Node的预期功能,因此(至少对我来说)修复是为了处理错误,我相信您是在未捕获的异常中完成的。尽管我在net.socket处理程序中处理它。
您可以证明这一点:
制作一个简单的套接字服务器并获得Node v0.9.9和v0.9.10。
# 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)
使用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。东西,它仍然会给出错误。同样,我认为这是有意的,解决方案是处理代码中的错误。
今天遇到了同样的问题。经过一番研究,我发现了一个非常有用的require('net')
.createServer( function(socket)
{
// no nothing
})
.listen(21, function()
{
console.log('Socket ON')
})
。它不仅提供了更多详细和有用的错误堆栈跟踪,而且还保存了应用程序崩溃时的核心文件,允许进一步调试。
我也遇到过同样的问题,但我通过放置以下内容缓解了它:
--abort-on-uncaught-exception
node.js option
--abort-on-uncaught-exception
之前。 server.timeout = 0;
是这里的HTTP服务器。根据server.listen
,默认超时为2分钟。
[另一种可能的情况(但罕见)是,如果您具有服务器之间的通信,并且将server
设置为非常低的值。
在节点的核心库API documentation中,它将调用server.maxConnections
,这也会导致错误ECONNRESET:
net.js
是,您提供的策略文件肯定会导致崩溃。
要重复,只需在您的代码中添加延迟:
clientHandle.close()
…并使用if (self.maxConnections && self._connections >= self.maxConnections) {
clientHandle.close(); // causes ECONNRESET on the other end
return;
}
连接到端口。如果在延迟到期之前断开telnet的连接,则在socket.write引发错误时会崩溃(未捕获的异常)。
为了避免此处崩溃,只需在读取/写入套接字之前添加错误处理程序:
net.createServer( function(socket)
{
for(i=0; i<1000000000; i++);
socket.write("<?xml version=\"1.0\"?>\n")
…
[尝试上述断开连接时,您只会收到一条日志消息,而不是崩溃。
完成后,请记住要消除延迟。
我在开发过程中也收到ECONNRESET错误,解决方法是通过not使用nodemon启动服务器,只需使用telnet
启动服务器即可解决我的问题。
这很奇怪,但是对我有用,现在我再也看不到ECONNRESET错误。
我也有这个错误,经过几天的调试和分析,也能够解决它:
对我来说,VirtualBox(对于Docker)是个问题。我在VM上配置了端口转发,并且错误仅在转发的端口上发生。
以下观察结果可能为您节省我不得不投资的工作时间:
->弄清您的网络(设置)是否有混乱,例如VM,防火墙等,这可能是问题的原因。