11

In the Node docs, http servers appear to have a close event:

Event: 'close'

function () { }

Emitted when the server closes.

But I can't figure out how to trigger it:

// server.js

var http = require('http');
var server = http.createServer();
server.on('close', function() {
  console.log(' Stopping ...');
});
server.listen(8000);

I expected the message "Stopping ..."

$ node server.js
^C Stopping ...
$ 

But instead there's nothing

$ node server.js
^C$ 

Does close mean something else here?

AJcodez
  • 31,780
  • 20
  • 84
  • 118
  • Hit! I posted the clean solution here: http://stackoverflow.com/questions/16698974/graceful-closing-of-node-expressjs-not-working/29019036#29019036 – Piotr Dajlido Mar 12 '15 at 19:55

4 Answers4

30

Killing the server with Ctrl+C doesn't allow the server to close itself; you have to do this yourself. Something like this should do the trick (on UNIX-like systems):

var http = require('http');
var server = http.createServer();
server.on('close', function() {
  console.log(' Stopping ...');
});

process.on('SIGINT', function() {
  server.close();
});

server.listen(8000);

Once the HTTP server closes and Node realizes there are no async operations that could be pending, it will automatically stop the process. If you have other stuff on the event loop (timers, etc.) and you want to force the event loop to stop after the server closes, close takes a callback:

process.on('SIGINT', function() {
  server.close(function() {
    process.exit(0);
  });
});
Michelle Tilley
  • 157,729
  • 40
  • 374
  • 311
4

You added an event handler for close. Use server.close(); to trigger the server event.

user568109
  • 47,225
  • 17
  • 99
  • 123
  • my experience is that the on('close') handler does not always fire, everything I have is set up correctly, so something else is amiss – Alexander Mills Mar 02 '17 at 19:37
1

Below is the snapshot , notice that i am closing the server after 2 seconds at last, so the event 'close' listener will perform callback function soon after. enter image description here

Incase you want code snippet:

const http = require('http');
const server = http.createServer();

// When Server starts listening
server.on('listening',()=>{
  console.log('Captured listening event');
});

// When User tries to connect to server
server.on('connection', ()=>{
  console.log('Connection Established');
});

// When the server is closed
server.on('close', ()=>{
  console.log('Connection terminated');
});


// 'listening' Event Fired
server.listen(3000);


// Close Server to get 'close' event fired
setTimeout(function(){
  server.close();
},2000);

Hope this helped :)

krupesh Anadkat
  • 1,932
  • 1
  • 20
  • 31
1

The server doesn't seem to fire any kind of close/finish/terminate event despite what is claimed in the doc. The workaround I found is to listen to the termination of the node process.

let wasCleanedUp = false;

const runBeforeExiting = (fun: Function) => {
  const exitSignals = ['exit', 'SIGINT', 'SIGUSR1', 'SIGUSR2', 'uncaughtException'];
  for (const signal of exitSignals) {
    process.on(signal as any, async () => { // eslint-disable-line @typescript-eslint/no-explicit-any
      if (!wasCleanedUp) {
        await fun();
        wasCleanedUp = true;
      }
      process.exit();
    });
  }
};

// And then before starting your server...
runBeforeExiting(() => {
  console.log('clean my application, close the DB connection, etc');
});

Of course it only works if serving requests is your process' only activity, but I assume it is the case in most servers.

OoDeLally
  • 552
  • 1
  • 5
  • 21