Chrome.tabs.sendMessage doesn't work while sendResponse is running
Here is the chrome extension manifest:
{
"name": "myconnector",
"short_name": "myconnector",
"version": "1.1",
"manifest_version": 2,
"description": "myapp",
"background": {
"scripts": ["main.js"],
"persistent": true
},
"externally_connectable": {
"ids": ["*"],
"matches": ["*://*.myurl.fr/*"]
},
"web_accessible_resources": [ "emulation.js", "content_scripts.js" ],
"icons": {
"16": "icon-16.png",
"128": "icon-128.png"
},
"permissions": [
"tabs",
"nativeMessaging"
]
}
Chrome extension background page:
//------ Message received from external web site
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if(request.areYouThere) {
onNativeMessage(true);
}
if(!port) {
port = chrome.runtime.connectNative(hostName);
//port.onMessage.addListener( onNativeMessage );
}
port.onMessage.addListener(function(msg) {sendResponse(msg);});
port.onDisconnect.addListener(function() {
console.log("Disconnected from native App");
port = null;
});
if (request.data) {
var data = request.data;
console.log(JSON.stringify(request));
port.postMessage(data);
}
return true;
});
// ----- Message received from Native Host App
function onNativeMessage( message ) {
console.log( 'received message from native app: ' + JSON.stringify( message ) );
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, message, function(response){});
});
}
And here is the code of the website calling the extension:
$("#my-action").click(function(){
console.log("calling method MyAction");
chrome.runtime.sendMessage( "<extension id>",
{data:
{action:"MyAction"}
},
function(response) {
console.log(JSON.stringify(response));
$("#result").text(JSON.stringify(response));
});
});
When I do this:
port.onMessage.addListener(function(msg) {sendResponse(msg);});
The answer posted correctly, but I get chrome.native.lastError.message:
It is not possible to send a response more than once per chrome .runtime.onMessage listener per document (the message was sent by extension for undefined url).
But when I do this:
port.onMessage.addListener( onNativeMessage );
This method, which calls onNativeMessage, sends a message to the website (presumably?) Using the chrome.tabs.sendMessage method. But the website never gets a response.
Also, my extension needs to instantiate the port so that it can use a persistent connection with my own host application.
Am I doing something wrong?
source to share
When I do this:
port.onMessage.addListener(function(msg) {sendResponse(msg);});
The answer was sent correctly, but I get
chrome.runtime.lastError.message
:It is not possible to send a response more than once to a
chrome.runtime.onMessage
listener per document (the message was posted by extension for URL undefined).
This is because you add a listener EVERY time you receive an external message. So after receiving the second message, it sendResponse()
tries to start twice (new and old again).
But when I do this:
port.onMessage.addListener( onNativeMessage );
This method, the caller
onNativeMessage
, sends a message to the website (presumably?) Using the methodchrome.tabs.sendMessage
. But the website never gets a response.
You cannot do this; chrome.tabs.sendMessage
sends the message to the content script context , not the web page.
You should change your code to only add listeners once, or at least provide simultaneous listening.
The trick, of course, is that the link sendResponse
changes every time. I think you can do it with a self destruct listener:
if(!port) {
port = chrome.runtime.connectNative(hostName);
port.onDisconnect.addListener(function() {
console.log("Disconnected from native App");
port = null;
});
}
var callback = function(msg) {
sendResponse(msg);
port.onMessage.removeListener(callback); // The power of closures!
};
port.onMessage.addListener(callback);
source to share