So, I create a port
var port = chrome.runtime.connectNative("my.native.app");
And I'll define
port.onMessage.addListener(onNativeMessage);
port.onDisconnect.addListener(onDisconnect);
So when I call
port.postMessage({"text":"messsage"});
It goes to my native application using standard in/out and I get my response.
Here's my problem: I have several functions that expect a response, and others that do not. I want to be able to post a message and wait for a response from the native application (which is continually running). How is this done?
I am aware of "one time messaging" via sendMessageNative
which works great, except I use my native application as a state machine, so it kills my application after it is done, which is no good.
You could add another listener to onNativeMessage
to call your callback and then de-register.
Something like this, with closures:
function callbackOnId(ev, id, callback) {
var listener = ( function(port, id) {
var handler = function(msg) {
if(msg.id == id) {
ev.removeListener(handler);
callback(msg);
}
}
return handler;
})(ev, id, callback);
ev.addListener(listener);
}
/* ... */
callbackOnId(port.onMessage, "someRequestId", callback);
port.postMessage({"text":"message", "id": "someRequestId"});
Now, the first time your port receives a message containing "id": "someRequestId"
, callback
will be called with that message, after which the listener will de-register itself.
If you need it, you can add an ability to remove the listener and/or modify the message checks.
My solution is to assign each message an unique id, and use a map to store the callback function for each message id (if there is a callback for the message).
When you receive a message from the host, check the message id and lookup the callback map. If there is a callback bound to that message, pass the response data and call it!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With