Skip to content

Commit dceebbf

Browse files
AndreasMadsenisaacs
authored andcommitted
child_process: allow sending a net Socket and Server object using child.send
child_process.fork() support sending native hander object, this patch add support for sending net.Server and net.Socket object by converting the object to a native handle object and back to a useful object again. Note when sending a Socket there was emitted by a net Server object, the server.connections property becomes null, because it is no longer possible to known when it is destroyed.
1 parent 49f16c4 commit dceebbf

File tree

6 files changed

+696
-31
lines changed

6 files changed

+696
-31
lines changed

doc/api/child_process.markdown

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ An alternative way to check if you can send messages is to see if the
5555
### Event: 'message'
5656

5757
* `message` {Object} a parsed JSON object or primitive value
58-
* `sendHandle` {Handle object} a handle object
58+
* `sendHandle` {Handle object} a Socket or Server object
5959

6060
Messages send by `.send(message, [sendHandle])` are obtained using the
6161
`message` event.
@@ -129,7 +129,7 @@ See `kill(2)`
129129
* `message` {Object}
130130
* `sendHandle` {Handle object}
131131

132-
When useing `child_process.fork()` an you can write to the child using
132+
When using `child_process.fork()` you can write to the child using
133133
`child.send(message, [sendHandle])` and messages are received by
134134
a `'message'` event on the child.
135135

@@ -162,9 +162,73 @@ the `message` event, since they are internal messages used by node core.
162162
Messages containing the prefix are emitted in the `internalMessage` event, you
163163
should by all means avoid using this feature, it is subject to change without notice.
164164

165-
The `sendHandle` option to `child.send()` is for sending a handle object to
166-
another process. The child will receive the object as its second argument to
167-
the `message` event.
165+
The `sendHandle` option to `child.send()` is for sending a TCP server or
166+
socket object to another process. The child will receive the object as its
167+
second argument to the `message` event.
168+
169+
**send server object**
170+
171+
Here is an example of sending a server:
172+
173+
var child = require('child_process').fork('child.js');
174+
175+
// Open up the server object and send the handle.
176+
var server = require('net').createServer();
177+
server.on('connection', function (socket) {
178+
socket.end('handled by parent');
179+
});
180+
server.listen(1337, function() {
181+
child.send('server', server);
182+
});
183+
184+
And the child would the recive the server object as:
185+
186+
process.on('message', function(m, server) {
187+
if (m === 'server') {
188+
server.on('connection', function (socket) {
189+
socket.end('handled by child');
190+
});
191+
}
192+
});
193+
194+
Note that the server is now shared between the parent and child, this means
195+
that some connections will be handled by the parent and some by the child.
196+
197+
**send socket object**
198+
199+
Here is an example of sending a socket. It will spawn two childs and handle
200+
connections with the remote address `74.125.127.100` as VIP by sending the
201+
socket to a "special" child process. Other sockets will go to a "normal" process.
202+
203+
var normal = require('child_process').fork('child.js', ['normal']);
204+
var special = require('child_process').fork('child.js', ['special']);
205+
206+
// Open up the server and send sockets to child
207+
var server = require('net').createServer();
208+
server.on('connection', function (socket) {
209+
210+
// if this is a VIP
211+
if (socket.remoteAddress === '74.125.127.100') {
212+
special.send('socket', socket);
213+
return;
214+
}
215+
// just the usual dudes
216+
normal.send('socket', socket);
217+
});
218+
server.listen(1337);
219+
220+
The `child.js` could look like this:
221+
222+
process.on('message', function(m, socket) {
223+
if (m === 'socket') {
224+
socket.end('You where handled as a ' + process.argv[2] + ' person');
225+
}
226+
});
227+
228+
Note that once a single socket has been sent to a child the parent can no
229+
longer keep track of when the socket is destroyed. To indicate this condition
230+
the `.connections` property becomes `null`.
231+
It is also recomended not to use `.maxConnections` in this condition.
168232

169233
### child.disconnect()
170234

@@ -382,7 +446,7 @@ leaner than `child_process.exec`. It has the same options.
382446

383447
This is a special case of the `spawn()` functionality for spawning Node
384448
processes. In addition to having all the methods in a normal ChildProcess
385-
instance, the returned object has a communication channel built-in. Se
449+
instance, the returned object has a communication channel built-in. See
386450
`child.send(message, [sendHandle])` for details.
387451

388452
By default the spawned Node process will have the stdout, stderr associated

doc/api/net.markdown

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,14 @@ Don't call `server.address()` until the `'listening'` event has been emitted.
198198
Set this property to reject connections when the server's connection count gets
199199
high.
200200

201+
It is not recommended to use this option once a socket has been sent to a child
202+
with `child_process.fork()`.
203+
201204
### server.connections
202205

203206
The number of concurrent connections on the server.
204207

208+
This becomes `null` when sending a socket to a child with `child_process.fork()`.
205209

206210
`net.Server` is an `EventEmitter` with the following events:
207211

0 commit comments

Comments
 (0)