Wie schließt man den Node.js Express-Server richtig?
Lesezeit: 6 Minuten
Wladimir Starkow
Ich muss den Server schließen, nachdem ich einen Rückruf erhalten habe /auth/github/callback
URL. Mit üblich HTTP-API Closing Server unterstützt derzeit mit server.close([callback])
API-Funktion, aber mit Node-Express-Server bekomme ich TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'close'
Error. Und ich weiß nicht, wie ich Informationen finden kann, um dieses Problem zu lösen. Wie soll ich den Express-Server schließen?
Außerdem habe ich ‘nodejs express close…’ gefunden, aber ich bin mir nicht sicher, ob ich es mit Code verwenden kann, den ich habe: var app = express();.
Ich starte einen Express in einen Komponententest. In diesem Bereich stoppt close() den Server nicht
– JRichardsz
6. Juni 2021 um 0:31 Uhr
@JRichardsz Vielleicht hatte sich die API in den letzten 8 Jahren geändert
Sie können Quellen einsehen: /node_modules/express/lib/application.js
Seltsam, es wird nicht geschlossen, wenn ich auf eine Route zugreife.
– Uday Hiwarale
18. Juli 2016 um 22:37 Uhr
@Uday, das habe ich auch erlebt. Ich fand heraus, dass in meinem Browser eine permanente HTTP1.1-Verbindung geöffnet war. Als ich also F5 drückte, schien es, als ob der Server nicht geschlossen wurde. Wenn Sie es mit einem anderen Browser versuchen, sehen Sie, dass der Server-Socket nicht läuft.
– Rick Velde
15. Dezember 2016 um 22:41 Uhr
Das war mein Fehler, ich war kurz davor app anstatt server. Meinen Tag gerettet. Vielen Dank 👍
– Edison Spencer
6. Dezember 2019 um 12:05 Uhr
Warum die Zeitüberschreitung?
– João Pimentel Ferreira
15. Juli 2021 um 12:39 Uhr
@JoãoPimentelFerreira Es scheint, dass Vladimir einfach dem Beispiel gefolgt ist, das OP gegeben hat, wo sie nach 3 Sekunden schließen
– Oleg Valter ist mit der Ukraine
15. Juli 2021 um 12:40 Uhr
Michael
In Express v3 haben sie diese Funktion entfernt.
Sie können dasselbe erreichen, indem Sie das Ergebnis von zuweisen app.listen() Funktion und wenden Sie es an:
var server = app.listen(3000);
server.close((err) => {
console.log('server closed')
process.exit(err ? 1 : 0)
})
Verwenden Sie so etwas wie github.com/gajus/http-terminator um sicherzustellen, dass der Server beendet wird, falls dauerhafte Verbindungen oder Anfragen bestehen, die keine Antwort erzeugen.
– Gajus
20. Januar 2020 um 3:16 Uhr
kurz und einfach
– krupesch Anadkat
28. Mai 2020 um 12:56 Uhr
Neha Sharma
Wenn in Ihrer Express-App ein Fehler auftritt, müssen Sie den Server schließen, und Sie können dies wie unten tun.
var app = express();
var server = app.listen(process.env.PORT || 5000)
Entschuldigung, es ist nicht relevant. Die Frage bezieht sich auf das manuelle Herunterfahren des Servers und nicht auf die Fehlerbehandlung
– Wladimir Starkow
1. Juli 2019 um 15:56 Uhr
bist du sicher server.close hat einen Rückruf? Ich sehe es nicht in der Dokumentation
– João Pimentel Ferreira
15. Juli 2021 um 12:40 Uhr
@JoãoPimentelFerreira – ja, das ist es sicherlich da
– Oleg Valter ist mit der Ukraine
15. Juli 2021 um 12:43 Uhr
@OlegValter danke, aber ich habe gelesen, dass der expressJs-Server nicht mehr vom http-Server von nodejs erbt
– João Pimentel Ferreira
15. Juli 2021 um 12:48 Uhr
@JoãoPimentelFerreira, als ich das letzte Mal nachgesehen habe, app.listen call tut es immer noch: „Die Methode app.listen() gibt ein http.Server-Objekt zurück und ist (für HTTP) eine bequeme Methode für Folgendes.“
– Oleg Valter ist mit der Ukraine
15. Juli 2021 um 12:58 Uhr
Ich habe viele Male auf verschiedenen Node.js-Supportkanälen auf eine Variation von „Wie man einen HTTP-Server beendet“ geantwortet. Leider kann ich keine der vorhandenen Bibliotheken empfehlen, da sie es sind fehlt auf die eine oder andere Weise. Seitdem habe ich ein Paket zusammengestellt, das (glaube ich) alle Fälle behandelt, die von einer ordnungsgemäßen Express.js-HTTP(S)-Serverbeendigung erwartet werden.
Es ist auch gut, auf System- (Benutzer-) Signale zu hören und sie auch ordnungsgemäß herunterzufahren, dafür sollten Sie auf beide hören SIGTERM und SIGINT
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);
});
});
João Pimentel Ferreira
Alte Frage, aber jetzt Node v18.2.0eingeführtserver.closeAllConnections(). Es sollte erwähnt werden, dass server.close führt seinen Rückruf nie aus, wenn der Browser die Anfrage sendet Connection: keep-aliveda server.close hält den Server nur davon ab, neue Verbindungen zu akzeptieren, alte Verbindungen werden nicht geschlossen.
Vor Node v18.2.0 habe ich dieses Problem gelöst, indem ich 5 Sekunden auf das Herunterfahren des Servers gewartet habe, wonach er das Beenden erzwingen würde.
Dieser Code umfasst beide Situationen
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)
}
}
Die meisten Antworten rufen an process.exit(), ich glaube nicht, dass das eine gute Idee ist. Sie müssen wahrscheinlich etwas Teardown durchführen, auch das ist einfach nicht nötig.
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());
Ich starte einen Express in einen Komponententest. In diesem Bereich stoppt close() den Server nicht
– JRichardsz
6. Juni 2021 um 0:31 Uhr
@JRichardsz Vielleicht hatte sich die API in den letzten 8 Jahren geändert
– Wladimir Starkow
8. Juni 2021 um 8:46 Uhr
@JRichardsz Siehe stackoverflow.com/a/21739334/1057730
– Wladimir Starkow
8. Juni 2021 um 8:47 Uhr
Ich denke, das Problem liegt am Mokka. Ich bereite ein minimal lauffähiges Muster vor. Meine Problemumgehung ist process.exit(0)
– JRichardsz
8. Juni 2021 um 14:12 Uhr
@JRichardsz es ist kein Mokka. process.exit(0) zur Problemumgehung ist die Axt für Kopfschmerzen.
– Wladimir Starkow
15. Juni 2021 um 9:19 Uhr