kakyo
kakyo

Reputation: 11590

nodejs/electron: stream pushes too many messages to child process

I'm sending messages from Electron frontend to a C++ child process through stdin over a button press, only to find that the button event triggers a series of the same sends.

What's the best practice to avoid redundant messages and ensure only one is sent?

Code

In the above code, I queue up the messages and send over the stream. But each button press seems to queue at least 5 messages.

// ./main.js


const stream = require('stream');

const hostProc = spawn(child, []);
var stdinStream = new stream.Readable();

const processCmd = exports.processCmd = (cmd) => {
    stdinStream.push(`${cmd}\n`); // Add data to the internal queue for users of the stream to consume
    stdinStream.pipe(hostProc.stdin);
};

Attempts

I've ensured that only one stream.push is called on each button press.

This button is just a simple HTML div, bound to a click listener

// ./button.js

const mainProc = remote.require('./main.js');

this.button.addEventListener('click', (evt) => { 
   var cmd = evt.msg;
   mainProc.processCmd(cmd);
   console.log('button: trigger');
}

Also made sure no redundant listeners were added to the button.

So the problem is definitely on the stream end.

Upvotes: 3

Views: 126

Answers (1)

kakyo
kakyo

Reputation: 11590

OK, solved it myself.

The problem was right in my code section

stdinStream.pipe(hostProc.stdin);

gets called every time we press the button. This effectively creates a new pipe on each call. That's why we received more and more redundant messages on child process end!

.pipe() is meant to "set up" the pipe connection, not a synonym of "send" or as such.

After moving this line to the global scope, the problem was gone.

Upvotes: 1

Related Questions