当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


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])。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。