Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I stop a Node.js HTTP server programmatically such that the process exits?

Tags:

I'm writing some tests and would like to be able to start/stop my HTTP server programmatically. Once I stop the HTTP server, I would like the process that started it to exit.

My server is like:

// file: `lib/my_server.js`

var LISTEN_PORT = 3000

function MyServer() {
  http.Server.call(this, this.handle) 
}

util.inherits(MyServer, http.Server)

MyServer.prototype.handle = function(req, res) { 
  // code 
}

MyServer.prototype.start = function() {
  this.listen(LISTEN_PORT, function() {
    console.log('Listening for HTTP requests on port %d.', LISTEN_PORT)
  })
}

MyServer.prototype.stop = function() {
  this.close(function() {
    console.log('Stopped listening.')
  })
}

The test code is like:

// file: `test.js`

var MyServer = require('./lib/my_server')
var my_server = new MyServer();

my_server.on('listening', function() {
  my_server.stop()
})

my_server.start()

Now, when I run node test.js, I get the stdout output that I expect,

$ node test.js
Listening for HTTP requests on port 3000.
Stopped listening.

but I have no idea how to get the process spawned by node test.js to exit and return back to the shell.

Now, I understand (abstractly) that Node keeps running as long as there are bound event handlers for events that it's listening for. In order for node test.js to exit to the shell upon my_server.stop(), do I need to unbind some event? If so, which event and from what object? I have tried modifying MyServer.prototype.stop() by removing all event listeners from it but have had no luck.

like image 895
Dmitry Minkovsky Avatar asked Jul 30 '13 22:07

Dmitry Minkovsky


People also ask

How do I stop HTTP server in node JS?

The server. close() method stops the HTTP server from accepting new connections. All existing connections are kept.

How do I stop a node JS execution code?

Method 1: Using the Ctrl+C key I hope everyone knows this shortcut to exit any Node. js process from outside. This shortcut can be used to stop any running process by hitting this command on terminal.

How do I stop a node server process?

To stop your NodeJS server from running, you can use the ctrl+C shortcut which sends the interrupt signal to the Terminal where you start the server.

Which function exits from the current node JS process?

exit function exits from the current Node. js process.


1 Answers

I've been looking for an answer to this question for months and I've never yet seen a good answer that doesn't use process.exit. It's quite strange to me that it is such a straightforward request but no one seems to have a good answer for it or seems to understand the use case for stopping a server without exiting the process.

I believe I might have stumbled across a solution. My disclaimer is that I discovered this by chance; it doesn't reflect a deep understanding of what's actually going on. So this solution may be incomplete or maybe not the only way of doing it, but at least it works reliably for me. In order to stop the server, you need to do two things:

  1. Call .end() on the client side of every opened connection
  2. Call .close() on the server

Here's an example, as part of a "tape" test suite:

test('mytest', function (t) {
    t.plan(1);

    var server = net.createServer(function(c) {
        console.log("Got connection");
        // Do some server stuff
    }).listen(function() {
        // Once the server is listening, connect a client to it
        var port = server.address().port;
        var sock = net.connect(port);

        // Do some client stuff for a while, then finish the test

        setTimeout(function() {
            t.pass();
            sock.end();
            server.close();
        }, 2000);

    });

});

After the two seconds, the process will exit and the test will end successfully. I've also tested this with multiple client sockets open; as long as you end all client-side connections and then call .close() on the server, you are good.

like image 179
user2041338 Avatar answered Oct 14 '22 09:10

user2041338