如何正确关闭 node-express 服务器?

Posted

技术标签:

【中文标题】如何正确关闭 node-express 服务器?【英文标题】:how to properly close node-express server? 【发布时间】:2013-01-09 01:42:53 【问题描述】:

收到/auth/github/callback的回调后我需要关闭服务器 网址。通常 HTTP API 关闭 服务器目前支持server.close([callback]) API 函数,但使用 node-express 服务器我得到TypeError: Object function app(req, res) app.handle(req, res); has no method 'close' 错误。而且我不知道如何查找信息来解决这个问题。我应该如何关闭快递服务器?

NodeJS 配置说明:

$ node --version
v0.8.17
$ npm --version
1.2.0
$ npm view express version
3.0.6

实际应用代码:

var app = express();

// configure Express
app.configure(function() 
    // … configuration
);

app.get(
    '/auth/github/callback',
    passport.authenticate('github',  failureRedirect: '/login' ),
    function(req, res) 
        res.redirect('/');

        setTimeout(function () 
            app.close();
            // TypeError: Object function app(req, res) app.handle(req, res);  has no method 'close'
        , 3000)
    
);

app.listen('http://localhost:5000/');

另外,我找到了‘nodejs express close…’,但我不确定是否可以将它与我拥有的代码一起使用:var app = express();

【问题讨论】:

我正在开始进行单元测试。在这个范围内,close() 不会停止服务器 @JRichardsz API 可能在过去 8 年发生了变化 @JRichardsz 见***.com/a/21739334/1057730 我认为问题出在摩卡咖啡上。我将准备一个最小的可运行样本。我的解决方法是 process.exit(0) @JRichardsz 这不是摩卡咖啡。 process.exit(0) 解决方法,是什么斧头令人头疼。 【参考方案1】:

如果您的 express 应用程序发生任何错误,那么您必须关闭服务器,您可以像下面那样执行此操作-

var app = express();
var server = app.listen(process.env.PORT || 5000)

如果发生任何错误,我们的应用程序将收到一个名为SIGTERM 的信号。您可以在此处阅读更多 SIGTERM - https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html

process.on('SIGTERM', () => 
  console.info('SIGTERM signal received.');
  console.log('Closing http server.');
  server.close((err) => 
    console.log('Http server closed.');
    process.exit(err ? 1 : 0);
  );
);

【讨论】:

对不起,它不相关。问题是关于手动关闭服务器,而不是关于错误处理 您确定server.close 有回调吗?我在文档中没有看到它 @JoãoPimentelFerreira - 是的,它是certainly there @OlegValter 谢谢,但我读到 expressJs 服务器不再从 nodejs http-server 继承 @JoãoPimentelFerreira 上次我检查时,app.listen 调用仍然有效:“app.listen() 方法返回一个 http.Server 对象并且(对于 HTTP)是以下的便捷方法” 【参考方案2】:

在 express v3 中,他们删除了这个功能。

您仍然可以通过分配 app.listen() 函数的结果并对其应用 close 来实现相同的目的:

var server = app.listen(3000);
server.close((err) => 
  console.log('server closed')
  process.exit(err ? 1 : 0)
)

https://github.com/visionmedia/express/issues/1366

【讨论】:

使用github.com/gajus/http-terminator 之类的东西来确保在存在持久连接或请求未产生响应的情况下终止服务器。 短小精悍【参考方案3】:

我已经在不同的node.js 支持频道上多次回答了“如何终止 HTTP 服务器”的变体。不幸的是,我不能推荐任何现有的库,因为它们以一种或另一种方式是lacking。从那以后,我整理了一个包,(我相信)它可以处理所有预期的优雅 express.js HTTP(S) 服务器终止的情况。

https://github.com/gajus/http-terminator

http-terminator 的主要好处是:

它不会对 Node.js API 进行猴子补丁 它会立即销毁所有没有附加 HTTP 请求的套接字 它允许对正在进行的 HTTP 请求的套接字进行优雅的超时 它可以正确处理 HTTPS 连接 它通过设置连接来通知使用 keep-alive 的连接服务器正在关闭:关闭标头 它不会终止 Node.js 进程

【讨论】:

谢谢你的回答,但这个问题已经有 7 年历史了 这仍然是一个有效的问题。【参考方案4】:

app.listen() 返回http.Server。您应该在该实例而不是 app 实例上调用 close()

例如

app.get(
    '/auth/github/callback',
    passport.authenticate('github',  failureRedirect: '/login' ),
    function(req, res) 
        res.redirect('/');

        setTimeout(function () 
            server.close();
            // ^^^^^^^^^^^
        , 3000)
    
);

var server = app.listen('http://localhost:5000/');

您可以查看来源:/node_modules/express/lib/application.js

【讨论】:

奇怪,如果我访问某些路线,它不会关闭。 @Uday,我也经历过。我发现我的浏览器打开了一个 HTTP1.1 持久连接,所以当我按下 F5 时,它看起来好像服务器没有关闭。如果您尝试使用其他浏览器,您将看到服务器套接字未运行。 那是我的错误,我在app 上调用close 而不是server。拯救了我的一天。非常感谢? 为什么会超时? @JoãoPimentelFerreira 似乎弗拉基米尔只是按照 OP 给出的示例在 3 秒后关闭

以上是关于如何正确关闭 node-express 服务器?的主要内容,如果未能解决你的问题,请参考以下文章

node-express 如何在 URL 查询字符串中传递 DATE 参数以及如何解析它

Node-express项目--个人简历:login(登录)接口编写记录

Node-express项目--个人简历:register(注册)接口编写记录

如何在 Node-Express / Vue Web 应用程序中管理 OAuth?

vue-cli 中的图像导致问题。 Node-Express,mysql后端

gulp-express实现node-express项目实时刷新