1

Hello i am very new to node.js and javascript, i am trying to create a culster.js with the nodejs cluster module, at the end of my if statement i am calling server.js to start the app.

cluster.js

const cluster = require('cluster');
const cpuCount = require('os').cpus().length;
const startServer = require('./server');

if (cluster.isMaster) {
  for (let i = 0; i < cpuCount; i += 1) {
    cluster.fork();
  }
  cluster.on('exit', () => {
    cluster.fork();
  });
} else {
  return startServer;
}

server.js

const fs = require('fs');
const path = require('path');

const express = require('express');
const auth = require('http-auth');
const {
  createBundleRenderer,
} = require('vue-server-renderer');

const bundle = fs.readFileSync('dist/server.js', 'utf-8');
const renderer = createBundleRenderer(bundle);

function parseIndexHtml() {
  const [
    entire,
    htmlOpen,
    htmlOpenTailAndHead,
    headCloseAndBodyOpen,
    bodyOpenTailAndContentBeforeApp,
    contentAfterAppAndHtmlClose,
  ] = fs.readFileSync('index.html', 'utf8').match(/^([\s\S]+?<html)([\s\S]+?)(<\/head>[\s\S]*?<body)([\s\S]+?)<div id="?app"?><\/div>([\s\S]+)$/);

  return {
    entire,
    htmlOpen,
    htmlOpenTailAndHead,
    headCloseAndBodyOpen,
    bodyOpenTailAndContentBeforeApp,
    contentAfterAppAndHtmlClose,
  };
}

const indexHtml = parseIndexHtml();
const app = express();

const basicAuth = auth.basic({
  realm: 'Jobportal',
}, (username, password, callback) => {
  callback(username === 'x' && password === 'x');
});

app.get('/ping', (request, response) => {
  response.status(200).end();
});

app.use(auth.connect(basicAuth));

// serve pure static assets
app.use('/public', express.static(path.resolve('./public')));
app.use('/dist', express.static(path.resolve('./dist')));

app.get('*', (request, response) => {
  const context = {
    url: request.url,
  };

  renderer.renderToString(context, (error, html) => {
    if (error) {
      if (error.code === '404') {
        response.status(404).end(indexHtml.entire);
      } else {
        response.status(500).end(indexHtml.entire);
        console.error(`Error during render: ${request.url}`); // eslint-disable-line
        console.error(error); // eslint-disable-line
      }
      return;
    }

    const {
      title,
      htmlAttrs,
      bodyAttrs,
      link,
      style,
      script,
      noscript,
      meta,
    } = context.meta.inject();

    response.write(
      `${indexHtml.htmlOpen} data-vue-meta-server-rendered ${htmlAttrs.text()} ${indexHtml.htmlOpenTailAndHead}
      ${meta.text()}
      ${title.text()}
      ${link.text()}
      ${style.text()}
      ${script.text()}
      <script>
        window.__INITIAL_STATE__ = ${JSON.stringify(context.initialState)}
      </script>
      ${noscript.text()}
      ${indexHtml.headCloseAndBodyOpen} ${bodyAttrs.text()} ${indexHtml.bodyOpenTailAndContentBeforeApp}
      ${html}
      <script src="/dist/client.js"></script>
      ${indexHtml.contentAfterAppAndHtmlClose}`
    );

    response.end();
  });
});

const port = 8181;

// start server
app.listen(port, () => {
  console.log(`server started at port ${port}`); // eslint-disable-line
});

I get an error

server started at port 8181
events.js:163
      throw er; // Unhandled 'error' event
      ^

Error: bind EADDRINUSE null:8181
    at Object.exports._errnoException (util.js:1050:11)
    at exports._exceptionWithHostPort (util.js:1073:20)
    at listenOnMasterHandle (net.js:1336:16)
    at rr (internal/cluster/child.js:111:12)
    at Worker.send (internal/cluster/child.js:78:7)
    at process.onInternalMessage (internal/cluster/utils.js:42:8)
    at emitTwo (events.js:111:20)
    at process.emit (events.js:194:7)
    at process.nextTick (internal/child_process.js:766:12)
    at _combinedTickCallback (internal/process/next_tick.js:73:7)
events.js:163
      throw er; // Unhandled 'error' event
      ^

Any ideas why ?

Momo
  • 61
  • 12

1 Answers1

2

EADDRINUSE means that the port number which listen() tries to bind the server to is already in use.

You need to verify if the port is already taken on your system. To do that:

  • On linux: sudo netstat -nltp | grep (port) in your case is port 8181.
  • On OSX: sudo lsof -i -P | grep (port)

If you have a result, you need to kill the process (kill <pid>).

You should check if pm2 list returns 0 process. In addition, when you do a pm2 stopAll, the socket is not released. Don't forget to do a pm2 kill to be sure the daemon is killed.

$ pm2 kill
Daemon killed

Verifying for Windows:

C:\> netstat -a -b
  • a Displays all connections and listening ports.

  • b Displays the executable involved in creating each connection or listening port. In some cases well-known executables host multiple independent components, and in these cases the sequence of components involved in creating the connection or listening port is displayed. In this case the executable name is in [] at the bottom, on top is the component it called, and so forth until TCP/IP was reached. Note that this option can be time-consuming and will fail unless you have sufficient permissions.

  • n Displays addresses and port numbers in numerical form.

  • o Displays the owning process ID associated with each connection.

EXAMPLES to kill in windows command line:

If you know the name of a process to kill, for example notepad.exe, use the following command from a command prompt to end it:

taskkill /IM notepad.exe

To kill a single instance of a process, specify its process id (PID). For example, if the desired process has a PID of 827, use the following command to kill it:

taskkill /PID 827
King Reload
  • 2,780
  • 1
  • 17
  • 42
  • Thanks for your help, i have already tried it out and the port is free to be used i get no answer. – Momo May 04 '17 at 08:37
  • @Momo note `server started at port 8181` in your console, means it already connects, but after that you try to connect another time – King Reload May 04 '17 at 08:38
  • correct ! and i guess it has to do with my if statement ! – Momo May 04 '17 at 08:40
  • Hope it helped ;) if you encounter `EADDRINUSE` again, it means the server tries to connect twice to the same address/port – King Reload May 04 '17 at 08:42
  • Thanks for your help. I still cant solve my problem :) with the code in cluster.js – Momo May 04 '17 at 08:46
  • `app.listen(port, () => {` and `return startServer;` do the same, try to put them on different ports, plus the `else {` in the `cluster.js` is meant for further processing. Here's a good example how to possibly resolve it: https://codeforgeek.com/2014/12/cluster-node-js-performance/ – King Reload May 04 '17 at 08:49
  • basically instead of `return startServer;` put inside it `require("./server.js");`. then in your console run `node cluster.js`. – King Reload May 04 '17 at 08:53
  • `return startServer;` in cluster.js meant to only call/run server.js. – Momo May 04 '17 at 09:01
  • @Momo have you looked at the documentation I send as well? #the wesbite – King Reload May 04 '17 at 09:02
  • Yes i did. with this code it works `var cluster = require('cluster'); 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 < cpuCount; i += 1) { cluster.fork(); } // Listen for dying workers cluster.on('exit', function () { cluster.fork(); }); } else { require('./server.js'); }` But i need to use the new way of writing which all require should be in top level and instead of var i use const. This where my problem came from. trying to convert this code – Momo May 04 '17 at 09:07
  • So you came to the solution? :) – King Reload May 04 '17 at 09:07
  • No i didnt with this code it works `var cluster = require('cluster'); 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 < cpuCount; i += 1) { cluster.fork(); } // Listen for dying workers cluster.on('exit', function () { cluster.fork(); }); } else { require('./server.js'); }` But i need to use the new way of writing which all require should be in top level and instead of var i use const. This where my problem came from. trying to convert this code – Momo May 04 '17 at 09:12
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/143372/discussion-between-king-reload-and-momo). – King Reload May 04 '17 at 09:14