NodeJS - how to get spawned child to communicate with parent?
Asked Answered
R

3

14

I'm trying this out:

var child = spawn('node', args, {cwd: parentDir, stdio: 'ipc'} );

(args is an array of parameters)

but it gives the following error:

TypeError: Incorrect value of stdio option: ipc

This actually works, so the problem seems indeed to be the stdio ipc parameter:

var child = spawn('node', args, {cwd: parentDir} );

This also works:

 var child = spawn('node', args, {cwd: parentDir, stdio: 'pipe'} );

I read this: http://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options but I don't see where I am going wrong. This is the first time I try to use this NodeJS functionality so I am sorry if the problem is evident.

Maybe there is some other way to solve the problem. The child has to be spawned and not forked and I simply want to be able to send messages from the child to the parent.

Thank you!!

EDIT: I have Node v0.8.18. I searched version history for IPC http://nodejs.org/changelog.html and there's nothing with search term "IPC" that makes me think that I need a newer version of NodeJS.

Roede answered 24/1, 2014 at 22:5 Comment(2)
do you need to specify the stdio option?Jury
I think so. Otherwise it does nothing by default (from the link I put in the text above). Here's what it says about IPC: 'ipc' - Create an IPC channel for passing messages/file descriptors between parent and child. A ChildProcess may have at most one IPC stdio file descriptor. Setting this option enables the ChildProcess.send() method. If the child writes JSON messages to this file descriptor, then this will trigger ChildProcess.on('message'). If the child is a Node.js program, then the presence of an IPC channel will enable process.send() and process.on('message').Roede
P
12

Here's a full example, slightly different from the other answers:

parent.js

spawn('node', ['child.js'], {
    stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
}).on('message', function(data) {
    console.log(data);
});
  • Child shares same cwdas the parent.
  • inherit is used to share the same streams (like stdout) with the child, so you can see stuff in your console for example.

child.js

process.send && process.send('hello parent');
  • If you're going to use the same code directly, the function won't be available (it'll be undefined), so you need to check first.
Pitapat answered 3/5, 2016 at 3:35 Comment(0)
G
5

Rockamic answered his own question, based on a couple of my nudges. Here's what worked & why:

 var child = spawn('node', args, {cwd: parentDir, stdio: [null, null, null, 'ipc']} );

specifying stdin, stdout, stderr, as null indicates default...

If rockamic comes back and provides his own answer, I will gladly delete this so he can get the accepted answer.

Greenwood answered 25/1, 2014 at 1:25 Comment(0)
G
0

try:

var child = spawn('node', ['childnodejsscript.js'], {cwd: parentDir, stdio: 'ipc'} );

(adding brackets to your arg which is supposed to be an array) and see if that alters your error-

if not perhaps

var child = spawn('node', ['childnodejsscript.js'], {cwd: parentDir, stdio: ['pipe', 1, 2, 'ipc']} );

And you may want to alter 'pipe', or address the stdout as well... not sure what you really want here.

finally, this seems like a good post to help you get some perspective. The title doesn't seem like a fit, but if you read what is happening in the code I think it'll be helpful:

http://blog.trevnorris.com/2013/07/child-process-multiple-file-descriptors.html

Don't forget to post results & help others with specifically what worked or what you changed... thx

Greenwood answered 24/1, 2014 at 22:39 Comment(4)
Thanks bellasys. Actually, I changed the initial code that I posted here (I simplified it) and instead of putting the actual variable there which I used that was an array I put the generic js name but you're right. Here's my actual code: child[port] = spawn('node', args, {cwd: parentDir, stdio: 'ipc'} ); I'll edit the original post. Thanks.Roede
I edited my answer suggesting a more robust treatment of your stdio: option. placing 'ipc' in the last slot e.g. [0,1,2,'ipc'] still gets you .send() and on('message') as you requested. If you are still having trouble, it's likely your context for this line is the trouble,not the line itself... FYI I referenced docs for your current version of Node (0.8.18) and 'ipc' seems valid for your version...Greenwood
Bellasys, I just saw your edit and have been toying around it for a few minutes now. That link gave me an idea (to look more into FDs) and here's what finally solved it: child[port] = spawn('node', args, {cwd: parentDir, stdio: [null, null, null, 'ipc'] } ); So yes, it was helpful indeed. THANK YOU! Have an excellent day.Roede
@Roede you can post your own answer to your own question. I suggest you do so for future overflowerzGreenwood

© 2022 - 2024 — McMap. All rights reserved.