可靠地从NodeJS中的FIFO中读取

时间:2018-11-27 03:42:11

标签: node.js fifo

我正在编写一个与第三方应用程序交互的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);
});

如果第3方应用程序正常运行,则效果很好。但是,在某些情况下,第三方应用程序将退出而无需写入文件/ FIFO。在这种情况下,脚本中的fs.open()调用将永远被阻止。 (请参见GitHub上的this related issue

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

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

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

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

谢谢!

1 个答案:

答案 0 :(得分:0)

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

$(document).ready(function() {
    var isBtn = localStorage.getItem("button");

    if(isBtn == "Removed")
    {
          $('.revoke-btn').remove()
    }

    $('.revoke-btn').click(function(e){
        e.preventDefault();
        var elem = jQuery(this);
        $.confirm({
            title:'Confirm?',
            content:'Confirm to revoke?',
            buttons:{
                confirm: {
                    text: 'Confirm',
                    btnClass: 'btn-danger',
                    action: function () {
                        localStorage.setItem("button", "Removed");
                        elem.remove();
                        var link = $(e.currentTarget).parent().attr('href');
                        window.location.href=link;
                    }
                },
                cancel: {
                    text: 'Cancel',
                    btnClass: 'btn-default'
                }
            }
        })
    });
});

这将打开fifo而不会阻塞,因为它同时连接了作者和读者。一个fifo可以有多个作者,因此第三方应用程序仍然可以连接,没有任何问题。