简体   繁体   中英

How to pass stream input/output between a main process and a child process in Node.js

I'm trying to get two processes to "talk" to each other via stdio :

ping.js

import { readline } from '../readline';
import { sleep } from '../sleep';
import { spawn } from 'child_process';

const spawnPongProcess = () => {
    const child = spawn('node',
        ['-r', 'esm', `${__dirname}/pong.js`],
        { stdio: 'pipe' });

    child.stderr.on('data', (data) => {
        console.error(`stderr: ${data}`);
    });

    child.on('close', (code) => {
        console.error(`child process exited with code ${code}`);
        process.stdin.resume();
        process.stdout.resume();
    });

    child.on('error', (err) => {
        console.error(`child process error: ${err}`);
    });

    process.stdout.pipe(child.stdin);
    child.stdout.pipe(process.stdin);

    return child;
};

export const ping = async () => {
    const child = spawnPongProcess();

    await sleep(1000);

    console.log('ping');

    let pong = readline();

    console.error(`Ping received: ${pong}`);

    child.kill();
};

I pipe the parent process' stdout to the child process stdin and the child process stdout to the parent process stdin in an effort to allow the processes to communicate via stdio .

pong.js

import { readline } from '../readline';
import { sleep } from '../sleep';

const pong = async () => {

    console.log(`Pong initiated and waiting for input.`);

    let ping = readline();

    console.log(`Pong received: ${ping}`);

    process.exit();
};

pong();

readline.js

import { question } from 'readline-sync';

export const readline = question;

sleep.js

export const sleep = (ms) => {
    return new Promise((resolve) => setTimeout(resolve, ms));
};

The output is:

$ node -r esm src/index.js
Pong initiated and waiting for input.
ping

It appears that the output from the parent process ( ping ) is not getting through to the child process ( pong ). Any ideas on how to make it work?

You piped your process' stdout (Writable) to child's stdin (Writable) and vice versa. Since data is received on the stdin (Readable), you have to pipe it instead of stdout :

process.stdin.pipe(child.stdin);
child.stdout.pipe(process.stdout);

Your code doesn't throw because if the stdout is a terminal, it becomes a Duplex stream.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM