Node.JSnetworking模块处理意外的连接丢失

我找不到我遇到的一个问题。 我在我的Node.JS服务器上使用Net模块来监听客户端连接。

客户端连接到服务器正确,连接保持可读/写数据。 到现在为止还挺好。 但是,当客户端意外断开(当互联网在客户端丢失时编辑),我想触发一个事件服务器端。

在socket.io中,它将使用'disconnect'事件完成,但是这个事件似乎并不存在于Net模块中。 怎么可能呢?

我在谷歌/ StackOverflow和networking文档( https://nodejs.org/api/net.html )上search,但我找不到任何有用的东西。 如果我做错了什么,我很好奇。

这是我得到的代码片段:

var net = require('net'); var server = net.createServer(function(connection) { console.log('client connected'); connection.wildcard = false;//Connection must be initialised with a configuration stored in the database connection.bidirectional = true;//When piped this connection will be configured as bidirectional connection.setKeepAlive(true, 500); connection.setTimeout(3000); connection.on('close', function (){ console.log('Socket is closed'); }); connection.on('error', function (err) { console.log('An error happened in connection' + err.stack); }); connection.on('end', function () { console.log('Socket did disconnect'); }); connection.on('timeout', function () { console.log('Socket did timeout'); connection.end(); }); connection.on('data', function (data) { //Handling incoming data }); }); serverUmrs.listen(40000, function () { console.log('server is listening'); }); 

所有的事件(closures,结束,错误,超时)不会触发当我断开客户端(拉出UTP电缆)。

提前致谢!

编辑:我没有在上面的代码中添加一个超时事件,但唯一发生的是,每次客户端再次连接3秒后套接字超时。 KeepAlive不足以使套接字不空闲? 怎样才能使sockets不空闲,没有太多的开销。 可能有超过10000个连接在同一时间,只要连接(即响应保持消息)就必须保持活动状态。

更新

我认为KeepAlivethe Idle state of socket没有关系,

这是我的testing,我在你的例子中删除了下面的代码。

 //connection.setKeepAlive(true, 500); 

然后用一个客户端连接到它的var nc localhost 40000来testing这个服务器。 如果3秒后没有信息发送到服务器,则服务器logging如下

 Socket did timeout Socket did disconnect Socket is closed 

timeout事件在没有KeepAlive设置的情况下被触发。

请进一步调查,参考Node.js 代码

 function onread(nread, buffer) { //... self._unrefTimer(); 

我们知道timeout事件是由onread()操作触发的。 也就是说,如果3秒后没有读取操作,则会发出timeout事件。 更确切地说,不仅是onread而且write成功将调用_unrefTimer()

总之,当对套接字进行写或读操作时,它不是空闲的。


实际上, close事件用来检测客户端连接是否存在,在这个SO 问题中也提到了。

服务器closures时发出。 请注意,如果存在连接,则在所有连接结束之前不会发出此事件。

但是,在你的情况

断开客户端(拔出UTP电缆)。

应该使用timeout事件来检测连接不活动。 这只是为了通知套接字已经空闲。 用户必须手动closures连接 。 请参考这个问题 。