代码之家  ›  专栏  ›  技术社区  ›  Joshua Walsh

在NodeJS中可靠地读取FIFO

  •  1
  • Joshua Walsh  · 技术社区  · 6 年前

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

    我的脚本创建了一个fifo:

    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);
    });
    

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

    为了解决这个问题,我用

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

    这可以防止我的脚本在第三方应用程序失败时挂起,但现在“数据”事件永远不会被触发,即使第三方应用程序工作正常。我想知道用OúNONBLOCK打开一个FIFO是否不算作打开它阅读?

    我不知道最好的解决办法是什么。目前我正在考虑推出第三方应用程序,等待10秒,看看它是否还在运行,然后打开fifo进行阅读,因为第三方应用程序很可能很快就会失败,如果它要失败的话。但这是一个黑客,所以我想知道什么是更好的解决方案。

    谢谢!

    1 回复  |  直到 6 年前
        1
  •  1
  •   Joshua Walsh    6 年前

    当然,我一问这个问题就想出来了。

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

    这将在不阻塞的情况下打开fifo,因为它同时连接一个写入器和一个读卡器。一个fifo可以有多个写入程序,因此第三方应用程序仍然可以连接而不出现任何问题。