如何正确关闭 Node.js TCP 服务器?

Posted

技术标签:

【中文标题】如何正确关闭 Node.js TCP 服务器?【英文标题】:How to properly close a Node.js TCP server? 【发布时间】:2015-03-16 06:59:33 【问题描述】:

我在 Google 或 SO 上找不到明确的答案。

我知道net.Server 实例有一个close 方法,它不允许更多的客户端进入。但它不会断开已经连接的客户端。我怎样才能做到这一点?

我知道用 Http 可以做到这一点,我想我是在问 Tcp 是一样的还是不一样的。

使用 Http,我会做这样的事情:

var http = require("http");

var clients = [];

var server = http.createServer(function(request, response) 
    response.writeHead(200, "Content-Type": "text/plain");
    response.end("You sent a request.");
);

server.on("connection", function(socket) 
    socket.write("You connected.");
    clients.push(socket);
);

// .. later when I want to close
server.close();
clients.forEach(function(client) 
    client.destroy();
);

Tcp 也一样吗?或者我应该做些什么不同的事情?

【问题讨论】:

是的,一样。如果您需要硬关机,请在执行server.close() 之前保留已连接客户端的列表并关闭所有活动(但如果真的“很难”,那么执行process.exit() 可能会更好) 不要忘记在它们断开连接时删除套接字(例如套接字的close 事件),否则您最终会得到一个包含潜在死套接字的不断增加的套接字数组。 【参考方案1】:

由于没有提供答案,以下是如何在 node.js 中打开和(硬)关闭服务器的示例:

创建服务器:

var net = require('net');

var clients = [];
var server = net.createServer();

server.on('connection', function (socket) 
    clients.push(socket);
    console.log('client connect, count: ', clients.length);

    socket.on('close', function () 
        clients.splice(clients.indexOf(socket), 1);
    );
);

server.listen(8194);

关闭服务器:

// destroy all clients (this will emit the 'close' event above)
for (var i in clients) 
    clients[i].destroy();

server.close(function () 
    console.log('server closed.');
    server.unref();
);

更新:自从使用上述代码后,我遇到了close 将使端口保持打开状态(Windows 中的 TIME_WAIT)的问题。由于我有意关闭连接,因此我使用unref,因为它似乎完全关闭了 tcp 服务器,但如果这是关闭连接的正确方法,我并不是 100%。

【讨论】:

TIME_WAIT 是内核,而不是进程,由于 TCP 协议规则,保持套接字处于活动状态。 Node.js 在创建新的 net.Server 时会设置 SO_REUSEADDR 标志,因此旧内核连接记录仍然存在这一事实不会影响进一步使用。

以上是关于如何正确关闭 Node.js TCP 服务器?的主要内容,如果未能解决你的问题,请参考以下文章

一文搞懂如何使用Node.js进行TCP网络通信

如何使用Docker Compose将容器A中的Node.js TCP客户端连接到容器B中的TCP服务器?

如何立即关闭Node.js http(s)服务器?

如何在 node.js 中监听随机 tcp 套接字

如何在 AngularJS 客户端和 Node.js 服务器之间重用代码 [关闭]

一文搞懂如何使用Node.js进行TCP网络通信