javascript 如何正确关闭Node.js Express服务器?

m528fe3b  于 2023-01-11  发布在  Java
关注(0)|答案(7)|浏览(478)

我需要关闭服务器后,从/auth/github/callback网址回调。与通常的**HTTP API**关闭服务器目前支持与server.close([callback]) API函数,但与节点表达服务器我得到TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'close'错误。我不知道如何找到信息来解决这个问题。

    • 如何关闭Express服务器?**

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();.

cuxqih21

cuxqih211#

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

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

vlju58qv

vlju58qv2#

在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

lb3vh1jj

lb3vh1jj3#

如果您的Express应用程序中发生任何错误,则必须关闭服务器,您可以像下面这样操作-

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

如果出现任何错误,我们的应用程序将获得一个名为SIGTERM的信号。

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);
  });
});
hc2pp10m

hc2pp10m4#

我在不同的node.js支持渠道上多次回答了“如何终止HTTP服务器”的问题。不幸的是,我不能推荐任何现有的库,因为它们在某种程度上是缺乏的。我已经整理了一个包,(我相信)可以处理所有预期的优雅express.js HTTP(S)服务器终止的情况。
https://github.com/gajus/http-terminator
http-terminator的主要优势在于:

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

oknrviil5#

调用server.close即可完成此任务

server.close((err) => {
  console.log('server closed')
  process.exit(err ? 1 : 0)
})

此外,监听系统(用户)信号并在它们上正常关闭也是很好的,因为您应该监听SIGTERMSIGINT

const port = process.env.PORT || 5000;
const server = app.listen(port);
console.log(`listening on port:${port}`);
for (let signal of ["SIGTERM", "SIGINT"])
    process.on(signal, () => {
        console.info(`${signal} signal received.`);
        console.log("Closing http server.");
        server.close((err) => {
            console.log("Http server closed.");
            process.exit(err ? 1 : 0);
        });
    });
jq6vz3qz

jq6vz3qz6#

老问题,但现在Nodev18.2.0引入了server.closeAllConnections()。需要注意的是,当浏览器发送请求Connection: keep-alive时,server.close从不运行其回调,因为server.close只会阻止服务器接受新连接,而不会关闭旧连接。
在Node v18.2.0之前,我通过等待5秒让服务器关闭来解决这个问题,之后它将强制退出。
此代码包含这两种情况

process.on('SIGINT', gracefulShutdown)
process.on('SIGTERM', gracefulShutdown)

function gracefulShutdown (signal) {
  if (signal) console.log(`\nReceived signal ${signal}`)
  console.log('Gracefully closing http server')

  // closeAllConnections() is only available from Node v18.02
  if (server.closeAllConnections) server.closeAllConnections()
  else setTimeout(() => process.exit(0), 5000)

  try {
    server.close(function (err) {
      if (err) {
        console.error('There was an error', err)
        process.exit(1)
      } else {
        console.log('http server closed successfully. Exiting!')
        process.exit(0)
      }
    })
  } catch (err) {
    console.error('There was an error', err)
    setTimeout(() => process.exit(1), 500)
  }
}
unhi4e5o

unhi4e5o7#

大多数的答案调用process.exit(),我不认为这是一个好主意。你可能需要执行一些拆卸,也根本不需要。

const server = app.listen(port);

server.on('close', () => {
  // Perform some teardown, for example with Knex.js: knex.destroy()
});

// FYI Docker "stop" sends SIGTERM
// If SIGTERM is not catched, Docker is forced to kill the container after ~10s
// and this provokes an exit code 137 instead of 0 (success)
process.on('SIGTERM', () => server.close());

查看Express.js 4.x文档:https://expressjs.com/en/advanced/healthcheck-graceful-shutdown.html#graceful-shutdown

相关问题