закрыть сервер изнутри роутера

Nov 16 2020

Я создаю такое экспресс-приложение

const express = require('express')
const app = express();

app.use(express.static(path.join(__dirname, 'public')));

app.post('/close', async (_, res) => {
  res.status(200);
  res.end();
  app.close();
});

module.exports = app;

Я создаю его в другом модуле

const myApp = require('./app.js');
myApp.listen(port, () => {
  console.log(`Started server on ${port}`);
});

Я хочу, чтобы сервер выключился, когда получит почтовый запрос к /close. На данный момент я просто получаю сообщение app.closeоб ошибке, а не функции.

Я знаю, что могу закрыть сервер таким образом

const server = myApp.listen(port, () => {
  console.log(`Started server on ${port}`);
});
server.close();

но я хочу закрыть сервер для отправки почтового запроса /close, как я могу это сделать?

Ответы

2 O.Jones Nov 16 2020 at 19:33

Чтобы получить доступ к вашему объекту сервера, попробуйте использовать

req.connection.server

из вашего обработчика маршрута.

.close()заставляет сервер перестать прислушиваться к новым соединениям. На уже установленные соединения это не влияет. Объект сервера генерирует 'close'событие, когда все открытые соединения отключены.

process.exit() останавливает все ваше приложение nodejs.

Итак, этот код может делать то, что вы хотите.

app.post('/close', (req, res, next) => {
  res.status(200)
  res.end()
  const server = req.connection.server
  if (server.listening) {
    server.addEventListener('close', ev => {
      console.log('server closed. See ya later alligator.')
      process.exit(0)
    })
    console.log('closing server')
    server.close()
  }
});

Если вам нужно получить объект сервера из объекта приложения (если получение его из объекта req недостаточно), вы можете добавить небольшую функцию промежуточного программного обеспечения, подобную этой.

app.use( function adornApp( req, res, next ) {
  req.app.locals.server = req.connection.server
  next()
} )

Тогда вы сможете получить свой сервер app.locals.serverпосле первого вызова промежуточного программного обеспечения.

Reyno Nov 16 2020 at 18:12

Вы можете использовать пакет http-terminator , чтобы закрыть свой сервер. Следующее должно помочь. Причина, по которой мы используем, http-terminatorзаключается в том, что сервер не закроется, если он будет посещен по маршруту.

const { createHttpTerminator } = require("http-terminator");
const { initApp, app } = require("./app.js");

const PORT = 3000;

const server = app.listen(PORT, () => {
  console.log(`Started server on ${PORT}`);
});

const httpTerminator = createHttpTerminator({ server });

initApp(httpTerminator);

Внутри модуля:

const express = require("express");
const app = express();

const initApp = (httpTerminator) => {
  app.get("/close", async (_, res) => {
    res.json({ message: "we closed" });
    await httpTerminator.terminate();
  });
};

module.exports = { initApp, app };