Nodejs 프로세스 간에 데이터 보내기

10735 단어 tutorialnodejavascript
저번달 오픈소스 프로젝트를 빌드하다가 자식프로세스에서 실행npm test을 하고 메인프로세스로 데이터를 다시 보내야하는 상황을 만났는데,

그래서 나는 약간의 조사를 했고 결국 해결책을 찾았습니다. 다음은 nodejs 프로세스 통신을 설정하는 데 사용할 수 있는 방법에 대한 요약입니다.

child_process.fork



fork는 기본적으로 통신 채널을 제공하고 자식 프로세스에 대한 파일을 지정하면 Nodejs 공식 문서에 표시된 것처럼 간단하게 자식 프로세스를 생성한 후 통신 채널을 설정합니다.

// index.js
import { fork } from 'node:child_process'
import path from 'path'

const subProcess = fork(path.resolve(process.cwd(),'sub.js'))
subProcess.on('message', (msg) => {
  console.log('PARENT got message: ', msg)
  subProcess.send('parent -> child')
})

// sub.js
process.send("child -> parent")
process.on('message', (msg) => {
  console.log('CHILD got message: ', msg)
})

// output
PARENT got message:  child -> parent
CHILD got message:  parent -> child


child_process.spawn



fork는 자식 프로세스에서 실행 중인 파일이 있는 경우에만 작동합니다. 다른 경우에는 자식 프로세스를 사용하여 명령을 실행하고 싶을 수 있으며 이러한 경우에 spawn을 사용합니다. 생성된 자식 프로세스는 stdio 매개 변수를 찾을 때까지 통신 채널을 설정할 수 없다고 생각했습니다. 예는 다음과 같습니다.

// index.js
import { spawn } from 'node:child_process'

const subProcess = spawn('node', ['sub.js'], {
  // inherit stdin, stdout and stderr, establish IPC communication channel
  stdio: ['inherit', 'inherit', 'inherit', 'ipc']  
})

subProcess.on('message', (msg) => {
  console.log('PARENT got message: ', msg)
  subProcess.send('parent -> child')
});

// sub.js
process.send("child -> parent")
process.on('message', (msg) => {
  console.log('CHILD got message: ', msg)
})

// output
PARENT got message:  child -> parent
CHILD got message:  parent -> child


stdout 또는 stderr 듣기



하지만 제 경우에는 npm 스크립트를 실행하기 위해 자식 프로세스가 필요합니다. 어떻게든 통신 채널을 설정할 수 없습니다.

마지막으로 stdout 또는 stderr를 통해 데이터를 전달하는 까다로운 솔루션으로 전환해야 합니다. 왜냐하면 부모 프로세스가 stdio를 파이프로 설정하면 자식 프로세스의 stdout 및 stderr에서 데이터를 수신할 수 있다는 것을 알았기 때문입니다. 그러면 우리가 해야 할 일은 다음과 같습니다. 부모 프로세스가 형식으로 데이터를 인식할 수 있도록 자식 프로세스가 미리 정의된 형식으로 데이터를 출력하도록 하십시오.

// index.js
const subProcess = spawn('node', 'run test', {
  // pipe stderr so we can subsribe the data event on stderr
  stdio: ['inherit', 'inherit', 'pipe']
});

subProcess.stderr.on('data', (buffer) => {
  const data = buffer.toString()
  if (data.startsWith('PREFIX')) {
    // Here we know this is the data sent from the child process manually
  }
})

// testing files
process.stderr.write('PREFIX' + 'message to parent' + "\n")


결론



노드 프로세스 간의 통신 채널을 설정하려면 다음을 수행하십시오.
  • 하위 프로세스에 대한 파일이 있는 경우 포크 사용
  • 자식 프로세스에서 명령을 실행하기만 하면 되는 경우 spawn 및 modify stdio 사용
  • NPM 스크립트를 실행 중인 경우 stdout 및 stderr를 통해 통신할 수 있습니다.
  • 좋은 웹페이지 즐겨찾기