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

12

我在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() 可能更好)。 - Andrey Sidorov
2
别忘了在socket断开连接时(例如socket的“close”事件)将其移除,否则你将得到一个不断增长的socket数组,其中可能包含无效的sockets。 - mscdex
3个回答

13

由于没有提供答案,这里提供一个在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服务器,尽管我不确定这是否是正确的关闭连接的方式。


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

0
  1. sock.end(); //正确地在两端发送连接结束信号
  2. sock.on("close", fn) //添加事件监听器以销毁所有相关的套接字和客户端
  3. sock.on("close", () => { sock.destroy() }) //销毁您的套接字包装器

示例:


  const closeConn = async (sock, cb) => {
    sock.ev.on("close", async ()=>{
      await sock?.destroy();
      if (typeof cb === "function") cb();
    });
    await sock?.end();
  }

  closeConn(sock, openSock);

您可以在这里查看更多信息


虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅有链接的答案可能会失效。-【来自审查】 - Rulisp

0

我正在使用NodeJS v16.13.2 ... 当包含服务器代码的进程退出时,默认情况下会关闭/销毁所有客户端连接。

我来这里是想找出如何监听server.("exit", myTaskCallback),因为我想在退出服务器时删除一些文件。但我找到的答案是这样的事件不存在。我必须监听process.on('exit', myTaskCallback)来完成工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接