Search code examples
javascriptangularjsgulpgulp-connect

Start and stop gulp-webserver


I am trying to start and stop gulp-webserver in different gulp tasks like below:

gulp.task('webserver', ['build'], function () {
    gulp.src([config.build, config.base])
    .pipe(webserver({
    livereload: false,
    directoryListing: false,
    open: true
  }));
});

gulp.task('webserver-stop', function () {
    var stream = gulp.src([config.build, config.base])
      .pipe(webserver());
    stream.emit('kill');
});

I am able to successfully start the server but when I try to stop the using gulp webserver-stop, it gives following error.

[19:36:30] Finished 'webserver-stop' after 27 ms
events.js:160
  throw er; // Unhandled 'error' event
  ^

Error: listen EADDRINUSE 127.0.0.1:8000
at Object.exports._errnoException (util.js:1008:11)
at exports._exceptionWithHostPort (util.js:1031:20)
at Server._listen2 (net.js:1253:14)
at listen (net.js:1289:10)
at net.js:1399:9
at GetAddrInfoReqWrap.asyncCallback [as callback] (dns.js:65:16)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:84:10)

I have no significant experience with gulp and javascript before, Any help to fix this please.


Solution

  • When you run gulp webserver and then gulp webserver-stop you have two processes. Those two processes know nothing of each other.

    So when you invoke webserver() in webserver-stop that just starts another webserver instance. It doesn't connect to the already running instance or anything like that. And since there is already one webserver running on port 8000 you get an EADDRINUSE error.

    Instead your webserver-stop task needs to send a message to the running webserver that causes it to shut down.

    Since you're already running a webserver you might as well send that message over HTTP. You can use the middleware option of gulp-webserver to achieve this:

    var gulp = require('gulp');
    var webserver = require('gulp-webserver');
    var http = require('http');
    
    gulp.task('webserver', function () {
      var stream = gulp.src(['.'])
        .pipe(webserver({
          livereload: false,
          directoryListing: false,
          open: true,
          middleware: function(req, res, next) {
            if (/_kill_\/?/.test(req.url)) {
              res.end();
              stream.emit('kill');
            }
            next();
          }
        }));
    });
    
    gulp.task('webserver-stop', function (cb) {
      http.request('http://localhost:8000/_kill_').on('close', cb).end();
    });
    

    Now you can invoke gulp webserver-stop in another terminal window or simply open http://localhost:8000/_kill_ in a browser to shut down the running webserver instance.