node.js - 在nodejs中将数据从子级管道传输到父级

标签 node.js pipe child-process

我有一个 nodejs 父进程启动另一个 nodejs 子进程。子进程执行一些逻辑,然后将输出返回给父进程。输出很大,我正在尝试使用管道进行通信,正如 child.send() 方法的文档中所建议的那样(顺便说一句,它工作得很好)。

我希望有人建议如何正确建立此沟通 channel 。我希望能够从 parent 向 child 发送数据,也希望能够从 child 向 parent 发送数据。我已经开始了一点,但它不完整(仅从 parent 向 child 发送消息)并引发错误。

父文件代码:

var child_process = require('child_process');

var opts = {
    stdio: [process.stdin, process.stdout, process.stderr, 'pipe']
};
var child = child_process.spawn('node', ['./b.js'], opts);

require('streamifier').createReadStream('test 2').pipe(child.stdio[3]);

子文件代码:

var fs =  require('fs');

// read from it
var readable = fs.createReadStream(null, {fd: 3});

var chunks = []; 

readable.on('data', function(chunk) {
    chunks.push(chunk);
});

readable.on('end', function() {
    console.log(chunks.join().toString());
})

上面的代码打印了预期的输出(“test 2”)以及以下错误:

events.js:85
      throw er; // Unhandled 'error' event
            ^
Error: shutdown ENOTCONN
    at exports._errnoException (util.js:746:11)
    at Socket.onSocketFinish (net.js:232:26)
    at Socket.emit (events.js:129:20)
    at finishMaybe (_stream_writable.js:484:14)
    at afterWrite (_stream_writable.js:362:3)
    at _stream_writable.js:349:9
    at process._tickCallback (node.js:355:11)
    at Function.Module.runMain (module.js:503:11)
    at startup (node.js:129:16)
    at node.js:814:3

完整答案:

家长代码:

var child_process = require('child_process');

var opts = {
    stdio: [process.stdin, process.stdout, process.stderr, 'pipe', 'pipe']
};
var child = child_process.spawn('node', ['./b.js'], opts);

child.stdio[3].write('First message.\n', 'utf8', function() {
    child.stdio[3].write('Second message.\n', 'utf8', function() {

    });
}); 

child.stdio[4].pipe(process.stdout);

child 的密码:

var fs =  require('fs');

// read from it
var readable = fs.createReadStream(null, {fd: 3});

readable.pipe(process.stdout);
fs.createWriteStream(null, {fd: 4}).write('Sending a message back.');

最佳答案

您的代码可以工作,但是通过使用 streamifier 包从字符串创建读取流,在传输该字符串后,您的通信 channel 会自动关闭,这就是您收到 ENOTCONN 错误的原因。

为了能够通过流发送多条消息,请考虑在其上使用 .write。您可以随意调用它:

child.stdio[3].write('First message.\n');
child.stdio[3].write('Second message.\n');

如果您想使用此方法发送多个离散消息(我相信这是基于您之前使用 child.send() 的评论的情况),最好使用一些分隔符号,以便在子项中读取流时能够拆分消息。在上面的示例中,我为此使用了换行符。 event-stream 是帮助这种拆分的一个有用的包。 .

现在,为了从父级中的子级创建另一个通信 channel ,只需将另一个“管道”添加到您的 stdio。

你可以在 child 里面写:

fs.createWriteStream(null, {fd: 4}).write('Sending a message back.');

并在父级中读取它:

child.stdio[4].pipe(process.stdout);

这将打印“发回消息”。到控制台。

关于node.js - 在nodejs中将数据从子级管道传输到父级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28946904/

相关文章:

node.js - FUNCTION_ERROR_INIT_FAILURE AWS lambda

javascript - 如何实现 node.js WebSocket 支持?

unix - FIFO 是否保留消息边界?

bash - 为什么管道中的重定向在 Bash 和 Zsh 中表现不同?

bash 使用陷阱 SIGCHLD 重新启动子进程?

每场比赛的 node.js 进程

node.js - Docker Express.js由于重定向到HTTPS而无法提供静态文件(也是Fastify的问题)

node.js - Nodejs - SPDY 推送请求错误

linux - 如何使用管道解析命令的输出

node.js - 他被杀死后如何重新连接到子进程?