如何以编程方式关闭 ExpressJS 的实例?

我正在想办法关闭 Express 的一个实例。基本上,我想要的反 .listen(port)调用-如何让一个 Express 服务器停止监听,释放端口,并关闭干净?

我知道这似乎是一个奇怪的问题,所以这里的上下文; ,也许有另一种方式来处理这个问题,我想它的方式是错误的。我正在为我的 socket.io/nodejs 应用程序设置一个测试框架。它是一个单页面的应用程序,因此在我的测试脚本中(我使用的是 摩卡,但这并不重要) ,我希望能够启动服务器,对其运行测试,然后关闭服务器。我可以通过假设服务器在测试开始之前就已经打开,或者通过让其中一个测试启动服务器并让后续的每个测试都假设服务器已经启动来解决这个问题,但是这真的很麻烦。我更希望每个测试文件使用适当的设置启动一个服务器实例,然后在测试结束时关闭该实例。这意味着运行测试没有奇怪的依赖关系,一切都是干净的。这也意味着我可以做启动/关闭测试。

有什么建议吗?我曾经想过手动触发异常来降低它,但是这看起来很麻烦。我已经查看了 Express 文档和源代码,但似乎找不到任何关闭服务器的方法。在 socket.io 中可能也有这样的功能,但是因为套接字服务器只是连接到 Express 服务器,所以我认为这需要在 Express 层进行。

66635 次浏览

通过编写 bash 脚本启动服务器、运行测试和停止服务器,可以很容易地完成这项工作。这样做的好处是允许您使用该脚本的别名来快速、轻松地运行所有测试。

我在整个持续部署过程中都使用这样的脚本。

使用 app.close()。完整的例子:

var app = require('express').createServer();
app.get('/', function(req, res){
res.send('hello world');
});
app.get('/quit', function(req,res) {
res.send('closing..');
app.close();
});
app.listen(3000);

当测试结束时,在回调中调用 app.close()。但请记住,进程仍在运行(尽管它不再监听)。

如果在此之后,您需要结束进程,那么调用 process.exit(0)

相关网址:

Close: http://nodejs.org/docs/latest/api/http.html#server.close(同样适用于)

出口: Http://nodejs.org/docs/latest/api/process.html#process.exit

由于 Express 服务器不再从节点 http 服务器继承,因此 发生了变化。幸运的是,app.listen 返回服务器实例。

var server = app.listen(3000);


// listen for an event
var handler = function() {
server.close();
};

我已经在不同的 支持通道上多次回答了“如何终止 HTTP 服务器”的变体。不幸的是,我不能推荐任何现有的库,因为它们在某种程度上都是 缺乏。后来我组装了一个包,(我相信)它可以处理所有优雅的 HTTP 服务器终止的情况。

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

http-terminator的主要好处是:

  • 它不是 Monkey-patch Node.js API
  • 它会立即销毁所有的套接字,而不附加 HTTP 请求
  • 它允许对持续 HTTP 请求的套接字进行优雅的超时
  • 它正确地处理 HTTPS 连接
  • 它使用 keep-alive 通知连接服务器正在通过设置一个连接: close header 关闭
  • 它不会终止 Node.js 进程

与 Express.js 的用法:

import express from 'express';
import {
createHttpTerminator,
} from 'http-terminator';


const app = express();


const server = app.listen();


const httpTerminator = createHttpTerminator({
server,
});


await httpTerminator.terminate();


//... some stuff


var server = app.listen(3000);
server.close();

最新版本的 Express 支持这一解决方案:

const server = app.listen(port);


const shutdown = () => {
server.close();
}