我正在使用Socket运行一个Express.js应用程序。IO的聊天网络应用程序 我在24小时内随机得到了5次以下错误。 节点进程永远被包装起来,并立即重新启动自己。

问题是重新启动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

编辑(2013-07-22)

增加了两个socket。IO客户端错误处理程序和未捕获的异常处理程序。 这个似乎捕获了错误:

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

所以我怀疑这不是插座。发送HTTP请求到另一个服务器 或者MySQL/Redis连接。问题在于错误堆栈 不能帮我找出我的代码问题。以下是日志输出:

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

我怎么知道是什么引起的呢?我如何从错误中得到更多?

好吧,不是很啰嗦,但这里是与朗约翰的堆栈跟踪:

    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会话突然关闭连接的末端。

您的互联网连接可能阻止您连接到某些服务器。在我的例子中,我试图连接到mLab(托管MongoDB数据库的云数据库服务)。我的网络服务提供商屏蔽了它。

其他回答

尝试将这些选项添加到socket.io:

const options = { transports: ['websocket'], pingTimeout: 3000, pingInterval: 5000 };

我希望这对你有帮助!

Node JS套接字不阻塞io。考虑使用来自其他源的非阻塞io连接。例如,如果使用带有node的阻塞Java套接字,它只会工作几秒钟,之后就会出现错误。通过实现一个非阻塞的连接来缓解这个问题,例如带有选择器的socketchannel。

当服务器端关闭TCP连接并且您对服务器的请求没有得到满足时,将发生ECONNRESET。服务器响应消息,表明您引用的连接无效。

为什么服务器发送无效连接的请求?

Suppose you have enabled a keep-alive connection between client and server. The keep-alive timeout is configured to 15 seconds. This means that if keep-alive is idle for 15 seconds, it will send connection close request. So after 15 seconds, server tells the client to close the connection. BUT, when server is sending this request, client is sending a new request which is already on flight to the server end. Since this connection is invalid now, server will reject with ECONNRESET error. So the problem occurs due to fewer requests to the server end. So please disable keep-alive and it will work fine.

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

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

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

并通过Telnet方式连接到该端口。如果在延迟过期之前断开telnet连接,当socket时将会出现崩溃(未捕获异常)。Write抛出错误。

为了避免这里的崩溃,只需在读写套接字之前添加一个错误处理程序:

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

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

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

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