child.send(message[, sendHandle[, options]][, callback])
-
message
<Object> -
sendHandle
<Handle> -
options
<Object> -
callback
<Function> - Return: <Boolean>
When an IPC channel has been established between the parent and child ( i.e. when using child_process.fork()
), the child.send()
method can be used to send messages to the child process. When the child process is a Node.js instance, these messages can be received via the process.on('message')
event.
For example, in the parent script:
const cp = require('child_process'); const n = cp.fork(`${__dirname}/sub.js`); n.on('message', (m) => { console.log('PARENT got message:', m); }); n.send({ hello: 'world' });
And then the child script, 'sub.js'
might look like this:
process.on('message', (m) => { console.log('CHILD got message:', m); }); process.send({ foo: 'bar' });
Child Node.js processes will have a process.send()
method of their own that allows the child to send messages back to the parent.
There is a special case when sending a {cmd: 'NODE_foo'}
message. All messages containing a NODE_
prefix in its cmd
property are considered to be reserved for use within Node.js core and will not be emitted in the child's process.on('message')
event. Rather, such messages are emitted using the process.on('internalMessage')
event and are consumed internally by Node.js. Applications should avoid using such messages or listening for 'internalMessage'
events as it is subject to change without notice.
The optional sendHandle
argument that may be passed to child.send()
is for passing a TCP server or socket object to the child process. The child will receive the object as the second argument passed to the callback function registered on the process.on('message')
event.
The options
argument, if present, is an object used to parameterize the sending of certain types of handles. options
supports the following properties:
-
keepOpen
- A Boolean value that can be used when passing instances ofnet.Socket
. Whentrue
, the socket is kept open in the sending process. Defaults tofalse
.
The optional callback
is a function that is invoked after the message is sent but before the child may have received it. The function is called with a single argument: null
on success, or an Error
object on failure.
If no callback
function is provided and the message cannot be sent, an 'error'
event will be emitted by the ChildProcess
object. This can happen, for instance, when the child process has already exited.
child.send()
will return false
if the channel has closed or when the backlog of unsent messages exceeds a threshold that makes it unwise to send more. Otherwise, the method returns true
. The callback
function can be used to implement flow control.
Example: sending a server object
The sendHandle
argument can be used, for instance, to pass the handle of a TCP server object to the child process as illustrated in the example below:
const child = require('child_process').fork('child.js'); // Open up the server object and send the handle. const server = require('net').createServer(); server.on('connection', (socket) => { socket.end('handled by parent'); }); server.listen(1337, () => { child.send('server', server); });
The child would then receive the server object as:
process.on('message', (m, server) => { if (m === 'server') { server.on('connection', (socket) => { socket.end('handled by child'); }); } });
Once the server is now shared between the parent and child, some connections can be handled by the parent and some by the child.
While the example above uses a server created using the net
module, dgram
module servers use exactly the same workflow with the exceptions of listening on a 'message'
event instead of 'connection'
and using server.bind
instead of server.listen
. This is, however, currently only supported on UNIX platforms.
Example: sending a socket object
Similarly, the sendHandler
argument can be used to pass the handle of a socket to the child process. The example below spawns two children that each handle connections with "normal" or "special" priority:
const normal = require('child_process').fork('child.js', ['normal']); const special = require('child_process').fork('child.js', ['special']); // Open up the server and send sockets to child const server = require('net').createServer(); 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);
The child.js
would receive the socket handle as the second argument passed to the event callback function:
process.on('message', (m, socket) => { if (m === 'socket') { socket.end(`Request handled with ${process.argv[2]} priority`); } });
Once a socket has been passed to a child, the parent is no longer capable of tracking when the socket is destroyed. To indicate this, the .connections
property becomes null
. It is recommended not to use .maxConnections
when this occurs.
Note: this function uses JSON.stringify()
internally to serialize the message
.
Please login to continue.