Alexander Mills
Alexander Mills

Reputation: 100320

Read from a 'named pipe' / fifo with Node.js

I have this:

  const p = path.resolve(projectRoot + '/NAMEDPIPEIN');
  const fd = fs.openSync(p, 'r+');

  fs.createReadStream(null, {fd}).on('data', function (d) {
    if (String(d).trim() === '[stdin end]') {
      return process.nextTick(cb);
    }
    process.argv.push(String(d).trim());
  });

I start the Node.js process, and then later, I write to the named pipe. For some reason no data seems to be arriving in the on data callback.

I am writing to named pipe like so:

 mkfifo NAMEDPIPEIN
 echo "foo bar baz" > NAMEDPIPEIN

Upvotes: 13

Views: 8652

Answers (2)

Sami
Sami

Reputation: 723

The other solution, from @richardpringle should work, but is limited in functionality.

If you try to open multiple FIFOs that way (more than the number of threads in the thread-pool), the first ones you opened won't be streaming data anymore. This is because the fs module isn't designed to work with file-descriptors in non-blocking mode. Instead, use the net module!

From https://stackoverflow.com/a/52622722/1843507 the current way to achieve streaming from a FIFO is using a socket:

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

fs.open('path/to/fifo/', fs.constants.O_RDONLY | fs.constants.O_NONBLOCK, (err, fd) => {
  // Handle err
  const pipe = new net.Socket({ fd });
  // Now `pipe` is a stream that can be used for reading from the FIFO.
  pipe.on('data', (data) => {
    // process data ...
  });
});

In summary, you can use @richardpringle's solution if you are running a script and don't mind tying up one of the threads in the thread-pool. Otherwise, you should definitely use this solution.

Upvotes: 14

richardpringle
richardpringle

Reputation: 791

This should do it:

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

const fifoPath = path.resolve(projectRoot, '/NAMEDPIPEIN')

const fifo = fs.createReadStream(fifoPath);

fifo.on('data', data => {
  // process data...
});

Use fifo.on('data', console.log) for testing.

Upvotes: 4

Related Questions