Как передать поток ввода / вывода между основным процессом и дочерним процессом в Node.js - PullRequest
0 голосов
/ 12 октября 2019

Я пытаюсь заставить два процесса «общаться» друг с другом через 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();
};

Я передаю родительский процесс 'stdoutдочернему процессу stdin и дочернему процессу stdout к родительскому процессу stdin, чтобы процессы могли обмениваться данными через 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));
};

Вывод:

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

Похоже, что выход из родительского процесса (ping) не проходит через дочерний процесс (pong). Любые идеи о том, как заставить это работать?

1 Ответ

1 голос
/ 12 октября 2019

Вы передали свой процесс 'stdout (доступный для записи) ребенку stdin (доступный для записи) и наоборот. Поскольку данные принимаются по stdin (для чтения), вы должны передать их вместо stdout:

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

Ваш код не выдает, потому что, если stdout является терминалом, он становитсяДуплексный поток.

...