title: How to setup clusters in expressjs 4.x app?
body: <p>I have an <a href="https://expressjs.com/en/starter/generator.html" rel="nofollow noreferrer">expressjs generated app</a> which is configured with socket io and I would like to implement <a href="https://nodejs.org/api/cluster.html" rel="nofollow noreferrer">nodejs clusters</a> in it. The problem is that in Express 4.x the server listening configuration is in the bin/www file and no longer in app.js file.
  Also my app is configured with socket io so I don't want to brake it too.</p>
  
  <p>This is how it should be implemented in express apps according to this <a href="https://rowanmanning.com/posts/node-cluster-and-express/" rel="nofollow noreferrer">article</a>:</p>
  
  <p>app.js</p>
  
  <pre><code>// Include the cluster module
  var cluster = require('cluster');
  
  // Code to run if we're in the master process
  if (cluster.isMaster) {
  
      // Count the machine's CPUs
      var cpuCount = require('os').cpus().length;
  
      // Create a worker for each CPU
      for (var i = 0; i &lt; cpuCount; i += 1) {
          cluster.fork();
      }
  
      // Listen for dying workers
      cluster.on('exit', function (worker) {
  
          // Replace the dead worker, we're not sentimental
          console.log('Worker %d died :(', worker.id);
          cluster.fork();
  
      });
  
  // Code to run if we're in a worker process
  } else {
  
      // Include Express
      var express = require('express');
  
      // Create a new Express application
      var app = express();
  
      // Add a basic route – index page
      app.get('/', function (request, response) {
          console.log('Request to worker %d', cluster.worker.id);
          response.send('Hello from Worker ' + cluster.worker.id);
      });
  
      // Bind to a port
      app.listen(3000);
      console.log('Worker %d running!', cluster.worker.id);
  }
  </code></pre>
  
  <p>And this is what I have:</p>
  
  <p>app.js</p>
  
  <pre><code>var createError = require('http-errors');
  var express = require('express');
  var path = require('path');
  var cookieParser = require('cookie-parser');
  var logger = require('morgan');
  
  var indexRouter = require('./routes/index');
  
  var app = express();
  var io = app.io = require('socket.io')();
  
  // view engine setup
  app.set('views', path.join(__dirname, 'views'));
  app.set('view engine', 'pug');
  
  app.use(logger('dev'));
  app.use(express.json());
  app.use(express.urlencoded({ extended: false }));
  app.use(cookieParser());
  app.use(express.static(path.join(__dirname, 'public')));
  
  app.use('/', indexRouter);
  
  // catch 404 and forward to error handler
  app.use(function(req, res, next) {
      next(createError(404));
  });
  
  // error handler
  app.use(function(err, req, res, next) {
      // set locals, only providing error in development
      res.locals.message = err.message;
      res.locals.error = req.app.get('env') === 'development' ? err : {};
  
      // render the error page
      res.status(err.status || 500);
      res.render('error');
  });
  
  var players = {};
  //socket io
  io.on('connection', function(socket) {
      socket.on('new player', function(data) {
          var player = {
              id: socket.id,
              name: data.name,
              color: data.color
          }
          players[socket.id] = player;
          io.to(`${socket.id}`).emit('player info', player);
      });
      socket.on('chat', function(data) {
          io.emit('message', {
              player: players[data.id],
              text: data.text
          });
      });
      socket.on('disconnect', function() {
          delete players[socket.id];
      });
  });
  module.exports = app;
  </code></pre>
  
  <p>bin/www</p>
  
  <pre><code>#!/usr/bin/env node
  
  /**
   * Module dependencies.
   */
  
  var app = require('../app');
  var debug = require('debug')('elvin:server');
  var http = require('http');
  
  /**
   * Get port from environment and store in Express.
   */
  
  var port = normalizePort(process.env.PORT || '80');
  app.set('port', port);
  
  /**
   * Create HTTP server.
   */
  
  var server = http.createServer(app);
  var io = app.io
  io.attach(server);
  
  /**
   * Listen on provided port, on all network interfaces.
   */
  
  server.listen(port, function(){
    console.log('server listening on port ' + server.address().port);
  });
  server.on('error', onError);
  server.on('listening', onListening);
  
  /**
   * Normalize a port into a number, string, or false.
   */
  
  function normalizePort(val) {
    var port = parseInt(val, 10);
  
    if (isNaN(port)) {
      // named pipe
      return val;
    }
  
    if (port &gt;= 0) {
      // port number
      return port;
    }
  
    return false;
  }
  
  /**
   * Event listener for HTTP server "error" event.
   */
  
  function onError(error) {
    if (error.syscall !== 'listen') {
      throw error;
    }
  
    var bind = typeof port === 'string'
      ? 'Pipe ' + port
      : 'Port ' + port;
  
    // handle specific listen errors with friendly messages
    switch (error.code) {
      case 'EACCES':
        console.error(bind + ' requires elevated privileges');
        process.exit(1);
        break;
      case 'EADDRINUSE':
        console.error(bind + ' is already in use');
        process.exit(1);
        break;
      default:
        throw error;
    }
  }
  
  /**
   * Event listener for HTTP server "listening" event.
   */
  
  function onListening() {
    var addr = server.address();
    var bind = typeof addr === 'string'
      ? 'pipe ' + addr
      : 'port ' + addr.port;
    debug('Listening on ' + bind);
  }
  </code></pre>
  
  <p>What do I do? The <code>module.exports = app;</code> is what it is causing me troubles </p>