Function callbacks being stripped from object in port.postMessage

709 views
Skip to first unread message

Robert Dailey

unread,
May 30, 2011, 8:33:45 PM5/30/11
to Chromium-extensions
From my content script, which does the chrome.extension.connect(), I have a function like so:


function Initialize( provider, callback )
{
var msg = {
action: 'initialize',
provider: provider,
cb: callback
}
port.postMessage( msg );
}


From my background page, which receives the message, the 'cb' parameter in my msg object is missing. It seems like chrome is stripping out any closures or functions I assign to my message object. Why is this happening? I need to pass a callback through my message request so that the response handler will be able to call the function with the results.

---------
Robert Dailey

Eric Williams

unread,
May 30, 2011, 9:07:46 PM5/30/11
to Robert Dailey, chromium-...@chromium.org

The message passing interface only supports sending the JSON-subset of
JavaScript types. (numeric & string literals, booleans, arrays, objects,
null) The documentation on message passing[1] mentions this limitation.

[1]: http://code.google.com/chrome/extensions/messaging.html

Robert Dailey

unread,
May 30, 2011, 9:14:45 PM5/30/11
to Eric Williams, chromium-...@chromium.org
Thanks I missed that piece..

So now I'm completely stumped on how I'm going to implement this. I guess I'll just have to use global variables to store the callback function so it can be invoked from the response handler in my content script. postMessage() doesn't take a callback method so I can't use a closure either.

---------
Robert Dailey

Michael Gundlach

unread,
May 31, 2011, 2:19:10 PM5/31/11
to Robert Dailey, Eric Williams, chromium-...@chromium.org
See chrome.extension.sendRequest, which the content script can use to call the background page.  The background page uses chrome.extension.onRequest, and can send a response back to the callback registered in sendRequest().

Under the hood, it's just using chrome.extension.connect and setting up a closure to wait for the callback, but the API is much nicer :)

Good luck,
Michael

--
You received this message because you are subscribed to the Google Groups "Chromium-extensions" group.
To post to this group, send email to chromium-...@chromium.org.
To unsubscribe from this group, send email to chromium-extens...@chromium.org.
For more options, visit this group at http://groups.google.com/a/chromium.org/group/chromium-extensions/?hl=en.

Robert Dailey

unread,
May 31, 2011, 2:24:16 PM5/31/11
to Michael Gundlach, Eric Williams, chromium-...@chromium.org
I really need to use connections here since I need a list of ports in the background page to post announcements to the content scripts. If I have both content scripts & the background page with listeners for sendRequest(), memory leaks occur because onRequest event handlers are being triggered from sendRequest() calls in non-content-script pages, such as the options page or other scripts in the background page.

If there is a way I can do a port.postMessage() and optionally specify a closure to receive the event response (instead of the port.onMessage handler), that would allow me to essentially do the same thing that sendRequest() is doing.

---------
Robert Dailey

Michael Gundlach

unread,
May 31, 2011, 2:42:52 PM5/31/11
to Robert Dailey, Eric Williams, chromium-...@chromium.org
On Tue, May 31, 2011 at 2:24 PM, Robert Dailey <rcda...@gmail.com> wrote:
I really need to use connections here since I need a list of ports in the background page to post announcements to the content scripts.

Hmm.. if you're saying that your content scripts need to send a callback to the background which the background will call much later, you could have the background page store up the 'sendResponse' objects passed to the onRequest listener.  I expect those will only be callable one time, though, unlike a port's postMessage().

If you needed to send multiple messages from the background page to content scripts without a request from the content script each time, then registering a port per content script and using port.postMessage() from the background page would be the way to go.
 
If I have both content scripts & the background page with listeners for sendRequest(), memory leaks occur because onRequest event handlers are being triggered from sendRequest() calls in non-content-script pages, such as the options page or other scripts in the background page.

I don't quite see why this is a memory leak.  If your background page does something like
  chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
    if (request.message == 'options-page-send-data')
      sendResponse(foo);
    else if (request.message == 'content-script-do-something')
      sendResponse(bar);
  });
then sendRequest() calls from any location will run your onRequest listener as expected.  Any other onRequest listeners will similarly make sure the request is directed to them before handling it.


If there is a way I can do a port.postMessage() and optionally specify a closure to receive the event response (instead of the port.onMessage handler), that would allow me to essentially do the same thing that sendRequest() is doing.

If the above hasn't answered your question, maybe tell us a bit more about what you're trying to accomplish.

Michael

Michael Gundlach

unread,
May 31, 2011, 2:44:42 PM5/31/11
to Robert Dailey, Eric Williams, chromium-...@chromium.org
On Tue, May 31, 2011 at 2:42 PM, Michael Gundlach <adblockf...@gmail.com> wrote:
If the above hasn't answered your question, maybe tell us a bit more about what you're trying to accomplish.

Whoops, I see you've got your answer in another thread.
Michael
Reply all
Reply to author
Forward
0 new messages