2015-01-20 71 views
0

我想'优雅地'关闭一个net.Server实例(用app.listen()创建)如果引发一个未处理的错误。服务器创建发生在我的bin/www脚本中。所有错误处理和路由中间件配置都在index.js中定义。为什么从不调用server.close回调?

在我的应用程序配置模块(index.js)中,我有错误处理中间件,它检查是否处理了每个错误。如果错误未被处理,则发出“关闭”事件。

注意:每个req和res包装在一个域中。我正在使用express-domain-middleware中间件模块来侦听每个req域上的错误事件,并将错误发送给我的错误处理。我只是提到这一点,以防它可能是罪魁祸首。

的“close_server”事件处理程序应该:

  1. 关闭服务器,使新的连接是不能接受的。
  2. 所有打开的连接完成后关闭当前进程。
  3. 如果10秒后服务器未关闭,强制进程关闭。

提供给server.close()的可选回调似乎永远不会被调用,我不知道为什么。为了测试这个,我做了一个引发错误的请求。该过程仅在计时器到期后(10秒过后)才关闭。

难道有什么东西在服务器中保持打开连接吗?为什么server.close()回调从未被调用?

谢谢!

更新 我正在使用Chrome向服务器发出请求。看起来浏览器正在打开一个连接。如果我使用curl发出请求,它会按预期工作。

看到这个issue

index.js

 app.use(function (err, req, res, next) { 
     if (typeof err.statusCode !== 'undefined') { 
      if (err.statusCode >= 500) { 
       Logger.error({error: err}); 
       return next(err); 
      } else { 
       Logger.warn({warn: err}); 
       return next(err); 
      } 
     } else { 
      //The error is un-handled and the server needs to go bye, bye 
      var unhandledError = new UnhandledError(util.format('%s:%s', req.method, req.originalUrl), 'Server shutting down!', err.stack, 500); 
      Logger.fatal({fatal: unhandledError}); 
      res.status(500).send('Server Error'); 
      app.emit('close_server', unhandledError); 
     } 
    }); 

斌/ WWW

#!/usr/bin/env node 
var app = require('../index');  
var port = config.applicationPort; 

app.set('port', port); 
var server = app.listen(app.get('port')); 

/* 
* Wait for open connections to complete and shut server down. 
* After 10 seconds force process to close. 
* */ 
app.on('close_server', function() { 
    server.close(function() { 
     console.log('Server Closed.'); 
     process.exit() 
    }); 
    setTimeout(function() { 
     console.log('Force Close.'); 
     process.exit() 
    }, 10 * 1000); 
}); 

回答

2

server.close()不关闭打开的客户端连接,它只是将停止接受新的连接

所以最有可能的Chrome浏览器发送带有Connection: keep-alive的请求,这意味着连接保持开启一段时间后出于效率的考虑(要能做出同样的连接上的多个请求),而卷曲可能是使用Connection: close,其中连接在服务器的响应之后立即切断。

相关问题