Schließen Sie den Server innerhalb des Routers

Nov 16 2020

Ich erstelle eine Express-App wie diese

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;

Ich instanziiere es in einem anderen Modul

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

Ich möchte, dass sich der Server selbst herunterfährt, wenn er eine Post-Anfrage an erhält /close. Im Moment bekomme ich nur einen app.closeist kein Funktionsfehler.

Ich weiß, dass ich einen Server so extern schließen kann

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

aber ich möchte den Server auf eine Post-Anfrage schließen /close, wie kann ich das tun?

Antworten

2 O.Jones Nov 16 2020 at 19:33

Versuchen Sie es mit, um Zugriff auf Ihr Serverobjekt zu erhalten

req.connection.server

aus Ihrem Routen-Handler heraus.

.close()macht den Server zu stoppen Hören für neue Verbindungen. Bereits hergestellte Verbindungen sind nicht betroffen. Das Serverobjekt gibt ein 'close'Ereignis aus, wenn alle offenen Verbindungen getrennt wurden.

process.exit() Stoppt Ihre gesamte NodeJS-App.

Dieser Code könnte also tun, was Sie wollen.

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

Wenn Sie das Serverobjekt von Ihrem App-Objekt abrufen müssen (wenn es nicht gut genug ist, um es von Ihrem Req-Objekt abzurufen), können Sie eine kleine Middleware-Funktion wie diese einsetzen.

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

Dann können Sie Ihren Server app.locals.serverabrufen, sobald Ihre Middleware zum ersten Mal aufgerufen wird.

Reyno Nov 16 2020 at 18:12

Sie können das http-terminator- Paket verwenden, um Ihren Server zu schließen. Das Folgende sollte den Trick machen. Der Grund, warum wir das verwenden, http-terminatorist, dass der Server nicht geschlossen wird, wenn er über eine Route besucht wird.

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

Innerhalb des Moduls:

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