tutorial principiantes para node libro examples docs desde cero node.js http connection keep-alive

node.js - principiantes - node js server express



¿Cómo cierro un servidor Node.js http(s) inmediatamente? (8)

Como han dicho otros, la solución es realizar un seguimiento de todos los sockets abiertos y cerrarlos manualmente. Mi paquete de nodos killable puede hacer esto por ti. Un ejemplo (usando express, pero puede llamar use killable en cualquier instancia http.server ):

var killable = require(''killable''); var app = require(''express'')(); var server; app.route(''/'', function (req, res, next) { res.send(''Server is going down NOW!''); server.kill(function () { //the server is down when this is called. That won''t take long. }); }); var server = app.listen(8080); killable(server);

Tengo una aplicación Node.js que contiene un servidor http (s).

En un caso específico, necesito apagar este servidor programáticamente. Lo que estoy haciendo actualmente es llamar a su función close() , pero esto no ayuda, ya que espera que las conexiones mantenidas activas terminen primero.

Entonces, básicamente, esto apaga el servidor, pero solo después de un tiempo de espera mínimo de 120 segundos. Pero quiero que el servidor se cierre de inmediato, incluso si esto significa romper con las solicitudes administradas actualmente.

Lo que no puedo hacer es un simple

process.exit();

ya que el servidor es solo una parte de la aplicación, y el resto de la aplicación debe seguir ejecutándose. Lo que estoy buscando es conceptualmente algo como server.destroy(); o algo así.

¿Cómo podría lograr esto?

PD: El tiempo de espera de mantener vivo para las conexiones generalmente es necesario, por lo tanto, no es una opción viable para disminuir este tiempo.


El truco es que debe suscribirse al evento de connection del servidor que le proporciona el conector de la nueva conexión. socket.destroy() recordar este socket y más adelante, directamente después de haber llamado a server.close() , destruir ese socket usando socket.destroy() .

Además, debe escuchar el evento de close del zócalo para eliminarlo de la matriz si se va de forma natural porque se agota el tiempo de espera para mantenerse activo.

He escrito una pequeña aplicación de muestra que puede usar para demostrar este comportamiento:

// Create a new server on port 4000 var http = require(''http''); var server = http.createServer(function (req, res) { res.end(''Hello world!''); }).listen(4000); // Maintain a hash of all connected sockets var sockets = {}, nextSocketId = 0; server.on(''connection'', function (socket) { // Add a newly connected socket var socketId = nextSocketId++; sockets[socketId] = socket; console.log(''socket'', socketId, ''opened''); // Remove the socket when it closes socket.on(''close'', function () { console.log(''socket'', socketId, ''closed''); delete sockets[socketId]; }); // Extend socket lifetime for demo purposes socket.setTimeout(4000); }); // Count down from 10 seconds (function countDown (counter) { console.log(counter); if (counter > 0) return setTimeout(countDown, 1000, counter - 1); // Close the server server.close(function () { console.log(''Server closed!''); }); // Destroy all open sockets for (var socketId in sockets) { console.log(''socket'', socketId, ''destroyed''); sockets[socketId].destroy(); } })(10);

Básicamente, lo que hace es iniciar un nuevo servidor HTTP, contar de 10 a 0 y cerrar el servidor después de 10 segundos. Si no se ha establecido ninguna conexión, el servidor se apaga inmediatamente.

Si se ha establecido una conexión y todavía está abierta, se destruye. Si ya había muerto naturalmente, solo se imprime un mensaje en ese momento.


Encontré una manera de hacer esto sin tener que hacer un seguimiento de las conexiones o tener que forzarlas a cerrar. No estoy seguro de qué tan confiable es en las versiones de Node o si hay consecuencias negativas a esto, pero parece funcionar perfectamente bien para lo que estoy haciendo. El truco es emitir el evento "cerrar" usando setImmediate justo después de llamar al método de close . Esto funciona así:

server.close(callback); setImmediate(function(){server.emit(''close'')});

Al menos para mí, esto termina liberando el puerto para poder comenzar un nuevo servicio HTTP (S) para cuando se llame a la devolución de llamada (que es prácticamente instantánea). Las conexiones existentes permanecen abiertas. Estoy usando esto para reiniciar automáticamente el servicio HTTPS después de renovar un certificado Let''s Encrypt.


La biblioteca https://github.com/isaacs/server-destroy proporciona una manera fácil de destroy() un servidor con el comportamiento deseado en la pregunta (mediante el seguimiento de las conexiones abiertas y la destrucción de cada una de ellas en la destrucción del servidor, como se describe en otra respuestas).


Mi mejor opción sería eliminar las conexiones manualmente (es decir, cerrarlas a la fuerza).

Idealmente, esto debería hacerse cavando en las partes internas del servidor y cerrando los enchufes a mano. Alternativamente, se podría ejecutar un comando de shell que haga lo mismo (siempre que el servidor tenga los privilegios adecuados, etc.)


Si necesita mantener vivo el proceso después de cerrar el servidor, entonces la solución de Golo Roden es probablemente la mejor.

Pero si cierra el servidor como parte de un cierre ordenado del proceso, solo necesita esto:

var server = require(''http'').createServer(myFancyServerLogic); server.on(''connection'', function (socket) {socket.unref();}); server.listen(80); function myFancyServerLogic(req, res) { req.connection.ref(); res.end(''Hello World!'', function () { req.connection.unref(); }); }

Básicamente, los sockets que usa su servidor solo mantendrán vivo el proceso mientras estén atendiendo una solicitud. Mientras están sentados sin hacer nada (debido a una conexión Keep-Alive), una llamada a server.close() cerrará el proceso, siempre y cuando no haya nada más que mantenga vivo el proceso. Si necesita hacer otras cosas después de que se cierre el servidor, como parte de su elegante cierre, puede enganchar en process.on(''beforeExit'', callback) para finalizar sus elegantes procedimientos de apagado.


Sin embargo, otro paquete nodejs para realizar un cierre matando las conexiones: github.com/thedillonb/http-shutdown , que parece razonablemente mantenido en el momento de la escritura (septiembre de 2016) y funcionó para mí en NodeJS 6.x

De la documentación

Uso

Actualmente hay dos formas de usar esta biblioteca. El primero es el ajuste explícito del objeto Servidor:

// Create the http server var server = require(''http'').createServer(function(req, res) { res.end(''Good job!''); }); // Wrap the server object with additional functionality. // This should be done immediately after server construction, or before you start listening. // Additional functionailiy needs to be added for http server events to properly shutdown. server = require(''http-shutdown'')(server); // Listen on a port and start taking requests. server.listen(3000); // Sometime later... shutdown the server. server.shutdown(function() { console.log(''Everything is cleanly shutdown.''); });

El segundo es agregar implícitamente funcionalidad prototipo al objeto Servidor:

// .extend adds a .withShutdown prototype method to the Server object require(''http-shutdown'').extend(); var server = require(''http'').createServer(function(req, res) { res.end(''God job!''); }).withShutdown(); // <-- Easy to chain. Returns the Server object // Sometime later, shutdown the server. server.shutdown(function() { console.log(''Everything is cleanly shutdown.''); });


process.exit (código); // código 0 para el éxito y 1 para el fracaso