如果同时发出请求,服务器只会在几分钟后关闭

Server closes only after a few minutes if a request is made in the meantime

我有服务器

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 操作似乎被延迟了。我能以某种方式使其即时吗?

虽然 @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);

    }
}