我使用node.js和socket.io来让我的网页访问TCP套接字提供的字符数据。我是node.js.的新手
用户---->网页<--(socket.io)-->node.js<--(TCP)-->TCP服务器
幸运的是,代码很简短:
io.on('connection', function (webSocket) {
tcpConnection = net.connect(5558, 'localhost', function() {});
tcpConnection.on('error', function(error) {
webSocket.emit('error', error);
tcpConnection.close();
});
tcpConnection.on('data', function(tcpData) {
webSocket.emit('data', { data: String.fromCharCode.apply(null, new Uint8Array(tcpData))});
});
});
在正常情况下一切都很好,但我不能保证TCP服务器会一直在那里。如果没有,TCP堆栈会向node.js返回ECONNREFUSED——这完全是意料之中的事,我需要优雅地处理它。目前,我看到:
events.js:72
throw er; // Unhandled 'error' event
^
Error: connect ECONNREFUSED
at errnoException (net.js:904:11)
at Object.afterConnect [as oncomplete] (net.js:895:19)
并且整个过程结束。
我做了很多工作来寻找解决方案;大多数点击似乎来自程序员,他们首先询问为什么收到ECONNREFUSED,而建议只是确保TCP服务器可用。没有讨论处理故障案例。
这个post-Node.js connectListener仍然在套接字错误时调用-建议像我在上面的代码中所做的那样为"error"事件添加一个处理程序。这正是我希望它工作的方式。。。除了没有(对我来说),我的程序没有捕获ECONNREFUSED。
我已经尝试过RTFM和node.js文档http://nodejs.org/api/net.html#net_event_error_1表明确实存在"错误"事件,但几乎没有给出如何使用它的线索
对其他类似SO帖子的回答(如Node.js错误:connect ECONNREFUSED)建议使用全局未捕获的异常处理程序,但这对我来说似乎是一个糟糕的解决方案。这不是我的程序由于错误代码而抛出异常,它工作得很好-它应该按照设计处理外部故障。
所以
- 我用正确的方式处理这个问题吗?(很高兴承认这是一个新手的错误)
- 有可能做我想做的事吗?如果有,怎么做
哦,还有:
$ node -v
v0.10.31
我运行了以下代码:
var net = require('net');
var client = net.connect(5558, 'localhost', function() {
console.log("bla");
});
client.on('error', function(ex) {
console.log("handled error");
console.log(ex);
});
由于我没有打开5558,输出为:
$ node test.js
handled error
{ [Error: connect ECONNREFUSED]
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect' }
这证明错误处理得很好。。。表明错误发生在其他地方。
正如在另一个答案中所讨论的,问题实际上是这条线:
webSocket.emit('error', error);
"error"事件是特殊的,需要在某个地方进行处理(如果不是,则流程结束)。
简单地将事件重命名为"问题"或"警告"会导致整个错误对象通过socket.io套接字传输回网页:
webSocket.emit('warning', error);
我找到的唯一解决方法是将网络内容封装在域中:
const domain = require('domain');
const net = require('net');
const d = domain.create();
d.on('error', (domainErr) => {
console.log(domainErr.message);
});
d.run(() => {
const client = net.createConnection(options, () => {
client.on('error', (err) => {
throw err;
});
client.write(...);
client.on('data', (data) => {
...
});
});
});
域错误捕获在创建网络客户端之前出现的错误情况,例如无效主机。
另请参阅:https://nodejs.org/api/domain.html