【问题标题】:Reliably reading from a FIFO in NodeJS在 NodeJS 中可靠地从 FIFO 中读取
【发布时间】:2018-11-27 03:42:10
【问题描述】:

我正在编写一个与第 3 方应用程序交互的 NodeJS 脚本。第三方应用程序将在文件打开期间将数据写入文件。我希望我的 NodeJS 应用程序能够实时接收这些数据。

我的脚本创建了一个先进先出:

child_process.spawnSync('mkfifo', [pipePath]);

然后它使用child_process.spawn 启动第三方应用程序。最后,它从管道中读取数据。

let pipeHandle = await promisify(fs.open)(pipePath, fs.constants.O_RDONLY);

let stream = fs.createReadStream(null, {fd: pipeHandle, autoClose: false});

stream.on('data', d => {
    console.log(d.length);
});

如果 3rd 方应用程序正常工作,这将非常有用。但是,在某些情况下,第 3 方应用程序将退出而不会写入文件/FIFO。在这种情况下,我的脚本中的 fs.open() 调用将永远阻塞。 (参见 GitHub 上的this related issue

为了解决这个问题,我使用了

let pipeHandle = await promisify(fs.open)(pipePath, fs.constants.O_RDONLY | fs.constants.O_NONBLOCK);

如果 3rd 方应用程序失败,这可以防止我的脚本挂起,但现在“数据”事件永远不会被触发,即使 3rd 方应用程序正常工作也是如此。我想知道使用 O_NONBLOCK 打开 FIFO 是否不算打开读取?

我不确定解决此问题的最佳方法是什么。目前我正在考虑启动 3rd 方应用程序,等待 10 秒,看看它是否仍在运行,然后打开 fifo 进行读取,因为如果第三方应用程序完全失败,它可能会很快失败。但这是一个 hack,所以我想知道更好的解决方案是什么。

谢谢!

【问题讨论】:

  • 根据 bnoordhuis 的评论,您是否想在您的 (pipePath, fs.constants.O_RDONLY | fs.constants.O_NONBLOCK)add 而不是使用按位或? (或者是他的建议中的错字?)
  • @CertainPerformance fs.constants.O_RDONLY + fs.constants.O_NONBLOCK 产生相同的结果。因为它们是位掩码,所以在这种情况下,操作执行完全相同的操作。它们都评估为 2048。

标签: node.js fifo


【解决方案1】:

当然,我一问问题就知道了。

let pipeHandle = await promisify(fs.open)(pipePath, fs.constants.O_RDWR);

这会在不阻塞的情况下打开 fifo,因为它同时连接了写入器和读取器。 fifo 可以有多个写入器,因此第 3 方应用程序仍然能够毫无问题地连接。

【讨论】:

    猜你喜欢
    • 2015-09-25
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-01
    相关资源
    最近更新 更多