Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Native Messaging postMessage with callback

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.

like image 736
Kirk Backus Avatar asked Dec 15 '22 04:12

Kirk Backus


2 Answers

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.

like image 145
Xan Avatar answered Dec 21 '22 07:12

Xan


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!

like image 44
Jun Avatar answered Dec 21 '22 05:12

Jun