强制关闭node.js http服务器中的所有连接

Mat*_*ski 30 http node.js

我有一个使用以下创建的http服务器:

var server = http.createServer()

我想关闭服务器.大概我会这样做:

server.close()

但是,这只会阻止服务器接收任何新的http连接.它不会关闭任何仍然打开的.http.close()接受回调,并且在所有打开的连接实际断开之前,回调不会执行.有没有办法强制关闭一切?

问题的根源在于我有Mocha测试,在他们的setup(beforeEach())中启动一个http服务器,然后在他们的拆卸(afterEach())中关闭它.但由于只是调用server.close()不会完全关闭,后续http.createServer()通常会导致EADDRINUSE错误.等待close()完成也不是一种选择,因为打开连接可能需要很长时间才能完成.

我需要一些强制关闭连接的方法.我可以做这个客户端,但强制关闭我的所有测试连接,但我宁愿做服务器端,即只是告诉http服务器硬关闭所有套接字.

Ege*_*can 40

你需要

  1. 订阅connection服务器的事件并将打开的套接字添加到数组
  2. 通过订阅他们的close事件并从阵列中删除已关闭的事件来跟踪打开的套接字
  3. destroy当您需要终止服务器时,调用所有剩余的打开套接字

您还有机会在子进程中运行服务器并在需要时退出该进程.


小智 9

对于遇到这个问题的其他人的参考,https://github.com/isaacs/server-destroy库提供了一种简单destroy()的服务器方式(使用Ege描述的方法).

  • @MaMa 比你想象的还要多。例如,该代码不适用于 HTTPS 服务器,不能很好地执行承诺,并且不能干净地关闭连接。世界在前进 - 如今,在我看来,https://www.npmjs.com/package/stoppable 是一个更好的选择。 (4认同)

den*_*nis 7

v18.2.0 中现在有一个closeAllConnections()方法


Elm*_*mer 6

我通常使用与此类似的东西:

var express = require('express');
var server = express();

/* a dummy route */
server.get('/', function (req, res) {
    res.send('Hello World!');
});

/* handle SIGTERM and SIGINT (ctrl-c) nicely */
process.once('SIGTERM', end);
process.once('SIGINT', end);


var listener = server.listen(8000, function(err) {
    if (err) throw err;

    var host = listener.address().address;
    var port = listener.address().port;

    console.log('Server listening at http://%s:%s', host, port);
});


var lastSocketKey = 0;
var socketMap = {};
listener.on('connection', function(socket) {
    /* generate a new, unique socket-key */
    var socketKey = ++lastSocketKey;
    /* add socket when it is connected */
    socketMap[socketKey] = socket;
    socket.on('close', function() {
        /* remove socket when it is closed */
        delete socketMap[socketKey];
    });
});

function end() {
    /* loop through all sockets and destroy them */
    Object.keys(socketMap).forEach(function(socketKey){
        socketMap[socketKey].destroy();
    });

    /* after all the sockets are destroyed, we may close the server! */
    listener.close(function(err){
        if(err) throw err();

        console.log('Server stopped');
        /* exit gracefully */
        process.exit(0);
    });
}
Run Code Online (Sandbox Code Playgroud)

就像EgeÖzcan所说的那样,只需在连接事件中收集套接字,然后在关闭服务器时销毁它们即可。


Jul*_*kis 5

我用现代 JS 重写了原始答案:

const server1 = http.createServer(/*....*/);
const server1Sockets = new Set();

server1.on("connection", socket => {
    server1Sockets.add(socket);
    socket.on("close", () => {
        server1Sockets.delete(socket);
    });
});

function destroySockets(sockets) {
    for (const socket of sockets.values()) {
        socket.destroy();
    }
}

destroySockets(server1Sockets);
Run Code Online (Sandbox Code Playgroud)