Sam*_*son 266 sockets tcp node.js express
我正在运行带有socket.io的Express js应用程序用于聊天webapp,并且我在24小时内随机获得以下错误5次左右.节点进程永远包装,并立即重新启动.
问题是重新启动快速将我的用户踢出他们的房间而没人想要.
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
Run Code Online (Sandbox Code Playgroud)
编辑(2013-07-22)
添加了socket.io客户端错误处理程序和未捕获的异常处理程序.似乎这个捕获了错误:
process.on('uncaughtException', function (err) {
console.error(err.stack);
console.log("Node NOT Exiting...");
});
Run Code Online (Sandbox Code Playgroud)
所以我怀疑它不是socket.io问题,而是对我做的另一个服务器的http请求或mysql/redis连接.问题是错误堆栈无法帮助我识别代码问题.这是日志输出:
Error: read ECONNRESET
at errnoException (net.js:900:11)
at TCP.onread (net.js:555:19)
Run Code Online (Sandbox Code Playgroud)
我怎么知道是什么原因造成的?如何从错误中获得更多信息?
好吧,不是很冗长,但这里是带有"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] ] } }
Run Code Online (Sandbox Code Playgroud)
在这里,我提供了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)
Run Code Online (Sandbox Code Playgroud)
这可能是原因吗?
e-s*_*shi 237
你可能已经猜到了:这是一个连接错误.
"ECONNRESET"意味着TCP对话的另一端突然关闭了它的连接结束.这很可能是由于一个或多个应用程序协议错误.您可以查看API服务器日志,看看它是否有抱怨.
但是既然你也在寻找一种检查错误并可能调试问题的方法,你应该看一下" 如何调试NodeJS中的套接字挂起错误? ",这是在stackoverflow上发布的,与一个类似的问题有关.
快速而肮脏的开发解决方案:
使用 longjohn,您将获得包含异步操作的长堆栈跟踪.
清晰且正确的解决方案:从技术上讲,在节点中,无论何时发出
'error'事件并且没有人收听它,它都会抛出.为了使它不被抛出,请在其上放置一个监听器并自己处理它.这样,您可以使用更多信息记录错误.要为一组调用创建一个侦听器,您可以使用域 并在运行时捕获其他错误.确保与http(服务器/客户端)相关的每个异步操作与代码的其他部分相比处于不同的域上下文中,域将自动侦听
error事件并将其传播到自己的处理程序.所以你只听那个处理程序并获取错误数据.您还可以免费获得更多信息.
编辑(2013-07-22)
正如我上面写的:
"ECONNRESET"意味着TCP对话的另一端突然关闭了它的连接结束.这很可能是由于一个或多个应用程序协议错误.您可以查看API服务器日志,看看它是否有抱怨.
也可能是这种情况:在随机时间,另一方面超载并且因此简单地杀死连接.如果是这种情况,取决于你正在连接的是什么......
但有一件事是肯定的:您确实在TCP连接上有读错误导致异常.您可以通过查看您在编辑中发布的错误代码来查看该错误代码.
Sam*_*son 36
我用于提供Flash策略文件的简单tcp服务器导致了此问题.我现在可以使用处理程序捕获错误:
# 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)
Run Code Online (Sandbox Code Playgroud)
Joh*_*ams 26
我有一个类似的问题,在升级Node后应用程序开始出错.我相信这可以追溯到Node release v0.9.10这个项目:
以前的版本不会在客户端中断时出错.来自客户端的连接中断会在Node中引发错误ECONNRESET.我相信这是Node的功能,所以修复(至少对我来说)是处理错误,我相信你在unCaught异常中做了.虽然我在net.socket处理程序中处理它.
你可以证明这一点:
创建一个简单的套接字服务器并获取Node v0.9.9和v0.9.10.
require('net')
.createServer( function(socket)
{
// no nothing
})
.listen(21, function()
{
console.log('Socket ON')
})
Run Code Online (Sandbox Code Playgroud)
使用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.一些东西,它仍然给出了错误.同样,我认为这是有意的,解决方案是处理代码中的错误.
小智 15
今天有同样的问题.经过一些研究,我发现了一个非常有用的--abort-on-uncaught-exceptionnode.js选项.它不仅提供了更加冗长和有用的错误堆栈跟踪,还在应用程序崩溃时保存了核心文件,允许进一步调试.
小智 13
我遇到了同样的问题,但我放置了以下内容:
server.timeout = 0;
Run Code Online (Sandbox Code Playgroud)
之前server.listen.server这是一个HTTP服务器.根据API文档,默认超时为2分钟.
另一种可能的情况(但很少见)可能是您有服务器到服务器通信并且设置server.maxConnections为非常低的值.
在节点的核心lib net.js中,它将调用clientHandle.close()哪个也会导致错误ECONNRESET:
if (self.maxConnections && self._connections >= self.maxConnections) {
clientHandle.close(); // causes ECONNRESET on the other end
return;
}
Run Code Online (Sandbox Code Playgroud)
小智 9
当服务器端关闭 TCP 连接并且您对服务器的请求未得到满足时,ECONNRESET就会发生。服务器响应一条消息,表明该连接,您指的是无效连接。
为什么服务器会发送无效连接的请求?
假设您已启用客户端和服务器之间的保持活动连接。保持活动超时配置为 15 秒。这意味着如果keep-alive空闲15秒,就会发送连接关闭请求。所以15秒后,服务器告诉客户端关闭连接。但是,当服务器发送此请求时,客户端正在发送一个已经在发送到服务器端的新请求。由于此连接现在无效,服务器将拒绝并显示 ECONNRESET 错误。所以出现这个问题是因为对服务器端的请求较少。所以请禁用keep-alive,它会正常工作。
是的,您提供的策略文件肯定会导致崩溃.
要重复,只需在代码中添加延迟:
net.createServer( function(socket)
{
for(i=0; i<1000000000; i++);
socket.write("<?xml version=\"1.0\"?>\n")
…
Run Code Online (Sandbox Code Playgroud)
...并用于telnet连接到端口.如果在延迟过期之前断开telnet,则当socket.write引发错误时,您将收到崩溃(未捕获的异常).
要避免崩溃,只需在读取/写入套接字之前添加错误处理程序:
net.createServer( function(socket)
{
for(i=0; i<1000000000; i++);
socket.on('error', function() { console.log("error"); });
socket.write("<?xml version=\"1.0\"?>\n")
Run Code Online (Sandbox Code Playgroud)
当您尝试上述断开连接时,您只需获取日志消息而不是崩溃.
当你完成后,记得删除延迟.
我通过简单地连接到不同的网络解决了这个问题。这是可能出现的问题之一。
如上所述,ECONNRESET意味着 TCP 会话突然关闭其连接端。
您的互联网连接可能会阻止您连接到某些服务器。就我而言,我尝试连接到 mLab(托管 MongoDB 数据库的云数据库服务)。我的 ISP 阻止了它。
我也有这个错误,经过几天的调试和分析后能够解决它:
对我来说 VirtualBox(用于 Docker)是问题所在。我在我的虚拟机上配置了端口转发,错误只发生在转发的端口上。
以下观察结果可以为您节省我不得不投入的工作天数:
-> 找出您的网络(-设置)是否有问题,例如虚拟机、防火墙等,这可能是问题的原因。
我在开发过程中也遇到ECONNRESET错误,解决问题的方法是不使用nodemon来启动服务器,而只是使用"node server.js"启动服务器来解决我的问题。
很奇怪,但是对我有用,现在我再也看不到ECONNRESET错误。
我通过以下方式解决了这个问题:
npm update在终端中输入: 来更新 npm。之后我尝试了相同的 npm 命令,幸运的是它成功了。我不确定事情有这么简单。
我使用的是CENTOS 7
我刚刚弄清楚了这一点,至少在我的用例中是这样。
我正在得到ECONNRESET。事实证明,按照我的客户端设置方式,它会非常快速地通过 API 调用多次访问服务器,而且只需要访问端点一次。
当我解决这个问题时,错误就消失了。
| 归档时间: |
|
| 查看次数: |
458752 次 |
| 最近记录: |