當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Node.js ChildProcess subprocess.send(message[, sendHandle[, options]][, callback])用法及代碼示例


subprocess.send(message[, sendHandle[, options]][, callback])

曆史
版本變化
v5.8.0

現在支持options 參數,尤其是keepOpen 選項。

v5.0.0

此方法現在返回一個用於流量控製的布爾值。

v4.0.0

現在支持callback 參數。

v0.5.9

添加於:v0.5.9


參數
  • message <Object>
  • sendHandle <Handle>
  • options <Object> options參數(如果存在)是用於參數化某些類型句柄的發送的對象。options支持以下屬性:
    • keepOpen <boolean> 傳遞 net.Socket 的實例時可以使用的值。當 true 時,套接字在發送過程中保持打開狀態。 默認: false
  • callback <Function>
  • 返回: <boolean>

當父子進程之間建立了 IPC 通道時(即使用 child_process.fork() 時),可以使用 subprocess.send() 方法向子進程發送消息。當子進程是 Node.js 實例時,可以通過 'message' 事件接收這些消息。

消息經過序列化和解析。生成的消息可能與最初發送的消息不同。

例如,在父腳本中:

const cp = require('node:child_process');
const n = cp.fork(`${__dirname}/sub.js`);

n.on('message', (m) => {
  console.log('PARENT got message:', m);
});

// Causes the child to print: CHILD got message: { hello: 'world' }
n.send({ hello: 'world' });

然後子腳本 'sub.js' 可能如下所示:

process.on('message', (m) => {
  console.log('CHILD got message:', m);
});

// Causes the parent to print: PARENT got message: { foo: 'bar', baz: null }
process.send({ foo: 'bar', baz: NaN });

子 Node.js 進程將擁有自己的 process.send() 方法,允許子進程將消息發送回父進程。

發送{cmd: 'NODE_foo'} 消息時有一種特殊情況。 cmd 屬性中包含 NODE_ 前綴的消息保留用於 Node.js 核心,不會在子級的 'message' 事件中發出。相反,此類消息是使用 'internalMessage' 事件發出的,並由 Node.js 在內部使用。應用程序應避免使用此類消息或偵聽 'internalMessage' 事件,因為它可能會發生更改,恕不另行通知。

可以傳遞給subprocess.send() 的可選sendHandle 參數用於將TCP 服務器或套接字對象傳遞給子進程。孩子將接收對象作為第二個參數傳遞給在 'message' 事件上注冊的回調函數。在套接字中接收和緩衝的任何數據都不會發送給孩子。

可選的callback 是一個函數,它在消息發送之後但在孩子可能收到消息之前被調用。該函數使用單個參數調用:成功時為null,失敗時為 Error 對象。

如果沒有提供callback 函數並且無法發送消息,則 ChildProcess 對象將發出'error' 事件。例如,當子進程已經退出時,就會發生這種情況。

subprocess.send() 將返回 false 如果通道已關閉或未發送消息的積壓超過閾值,導致發送更多消息是不明智的。否則,該方法返回 truecallback函數可用於實現流量控製。

示例:發送服務器對象#

例如,sendHandle 參數可用於將 TCP 服務器對象的句柄傳遞給子進程,如下例所示:

const subprocess = require('node:child_process').fork('subprocess.js');

// Open up the server object and send the handle.
const server = require('node:net').createServer();
server.on('connection', (socket) => {
  socket.end('handled by parent');
});
server.listen(1337, () => {
  subprocess.send('server', server);
});

然後,孩子將收到服務器對象:

process.on('message', (m, server) => {
  if (m === 'server') {
    server.on('connection', (socket) => {
      socket.end('handled by child');
    });
  }
});

一旦服務器現在在父母和孩子之間共享,一些連接可以由父母處理,一些由孩子處理。

雖然上麵的示例使用使用 node:net 模塊創建的服務器,但 node:dgram 模塊服務器使用完全相同的工作流程,但偵聽 'message' 事件而不是 'connection' 以及使用 server.bind() 而不是 server.listen() 。但是,目前僅在 Unix 平台上支持。

示例:發送套接字對象#

同樣,sendHandler 參數可用於將套接字句柄傳遞給子進程。下麵的示例生成了兩個子節點,每個子節點處理具有 "normal" 或 "special" 優先級的連接:

const { fork } = require('node:child_process');
const normal = fork('subprocess.js', ['normal']);
const special = fork('subprocess.js', ['special']);

// Open up the server and send sockets to child. Use pauseOnConnect to prevent
// the sockets from being read before they are sent to the child process.
const server = require('node:net').createServer({ pauseOnConnect: true });
server.on('connection', (socket) => {

  // If this is special priority...
  if (socket.remoteAddress === '74.125.127.100') {
    special.send('socket', socket);
    return;
  }
  // This is normal priority.
  normal.send('socket', socket);
});
server.listen(1337);

subprocess.js 將接收套接字句柄作為傳遞給事件回調函數的第二個參數:

process.on('message', (m, socket) => {
  if (m === 'socket') {
    if (socket) {
      // Check that the client socket exists.
      // It is possible for the socket to be closed between the time it is
      // sent and the time it is received in the child process.
      socket.end(`Request handled with ${process.argv[2]} priority`);
    }
  }
});

不要在已傳遞給子進程的套接字上使用.maxConnections。父級無法跟蹤套接字何時被銷毀。

子進程中的任何'message' 處理程序都應驗證socket 存在,因為在將連接發送給子進程所需的時間期間連接可能已關閉。

相關用法


注:本文由純淨天空篩選整理自nodejs.org大神的英文原創作品 subprocess.send(message[, sendHandle[, options]][, callback])。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。