NodeJS 如果在此期间发出请求,服务器仅在几分钟后关闭

nfg76nw0  于 2023-05-28  发布在  Node.js
关注(0)|答案(1)|浏览(92)

我有服务器

var connect = require('connect');
var serveStatic = require('serve-static');

var HTMLServer = function(path){
    this.path = path;
    this.server = connect().use(serveStatic(this.path));

    this.startServer = function(callback){
        this.server = this.server.listen(8080, callback);
    };
    this.stopServer  = function(callback){
        this.server.close(callback);
    }
}

我使用它如下:

var thisServer = new HTMLServer(__dirname);
thisServer.startServer(function(){
    console.log('Server running on 8080...');
    setTimeout(function(){
        thisServer.stopServer(function(){
            console.log('Server closed');
        });
    }, 3000);

});

正如预期的那样,服务器启动并在3000毫秒后停止。

但是,如果我在这3000毫秒内向这个服务器发出请求,stopServer被调用,但是服务器没有关闭。

我确信这行this.server.close(callback);会被执行,但不会像我期望的那样关闭服务器。
我该怎么弥补?
对服务器的请求是否以需要特殊处理的方式更改服务器示例?

后期编辑:

我想添加一些精确度,现在我离开了代码运行。似乎服务器确实关闭了,但不是立即关闭,而是在一段时间之后,我不明白,不超过5分钟。
所以close操作似乎被延迟了。我能以某种方式让它变得即时吗?

chhkpiq4

chhkpiq41#

虽然@jfriend00是正确的,node.js会一直运行,直到所有退出的套接字完成,但process.exit解决方案对我的用例来说有点太激进了,我需要一个更干净的解决方案来优雅地关闭服务器。
查看getConnections只会增加更多的困惑,因为它没有按预期运行。(例如,即使我没有发出任何请求,它也返回了2个连接)。
我还查看了server.listening,但即使服务器接受更多请求,它也返回false。可能在关闭服务器之前接受来自发出请求的客户端的连接。
无论如何,对我来说,解决方案是使用http-shutdown库,它本质上是将以下.shutdown方法添加到server对象中。

function addShutdown(server) {
  var connections = {};
  var isShuttingDown = false;
  var connectionCounter = 0;

  function destroy(socket, force) {
    if (force || (socket._isIdle && isShuttingDown)) {
      socket.destroy();
      delete connections[socket._connectionId];
    }
  };

  function onConnection(socket) {
    var id = connectionCounter++;
    socket._isIdle = true;
    socket._connectionId = id;
    connections[id] = socket;

    socket.on('close', function() {
      delete connections[id];
    });
  };

  server.on('request', function(req, res) {
    req.socket._isIdle = false;

    res.on('finish', function() {
      req.socket._isIdle = true;
      destroy(req.socket);
    });
  });

  server.on('connection', onConnection);
  server.on('secureConnection', onConnection);

  function shutdown(force, cb) {
    isShuttingDown = true;
    server.close(function(err) {
      if (cb) {
        process.nextTick(function() { cb(err) });
      }
    });

    Object.keys(connections).forEach(function(key) {
      destroy(connections[key], force);
    });
  };

  server.shutdown = function(cb) {
    shutdown(false, cb);
  };

  server.forceShutdown = function(cb) {
    shutdown(true, cb);
  };

  return server;
};

有了这个函数,我可以如下更新我的服务器,现在stopServer可以按预期工作了:

var HTMLServer = function(path){
    this.path = path;
    this.server = connect().use(serveStatic(this.path));
    this.startServer = function(callback){
        this.server = addShutdown(this.server.listen(8080, callback));
    };

    this.stopServer  = function(callback){
        console.log("I was called");
        this.server.shutdown(callback);

    }
}

相关问题