I am trying to establish the communication between the web page and the native application, so that
- The web page could send events to the native application, for example, by clicking a button
- The native application could send events back to the web page which could be handled by JavaScript handlers
I'm trying to use Chrome Native Messaging: https://developer.chrome.com/extensions/nativeMessaging
The example provided by Chrome works well (needed however some adjustment to run on Python 3.8), but that example is the Chrome application which doesn't seem to fit my purposes.
I changed the code so that the Application became the Extension, and the application JS script became the extension content script.
Here is the updated manifest.json:
{
// Extension ID: knldjmfmopnpolahpmmgbagdohdnhkik
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcBHwzDvyBQ6bDppkIs9MP4ksKqCMyXQ/A52JivHZKh4YO/9vJsT3oaYhSpDCE9RPocOEQvwsHsFReW2nUEc6OLLyoCFFxIb7KkLGsmfakkut/fFdNJYh0xOTbSN8YvLWcqph09XAY2Y/f0AL7vfO1cuCqtkMt8hFrBGWxDdf9CQIDAQAB",
"name": "Native Messaging Example",
"version": "1.0",
"manifest_version": 2,
"description": "Send a message to a native application.",
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["main.js"]
}
],
"icons": {
"128": "icon-128.png"
},
"permissions": [
"nativeMessaging"
]
}
The extension starts after the webpage is loaded. To send events from the webpage to the extension, I used "Communication with the embedded page" mechanism described here: https://developer.chrome.com/extensions/content_scripts
Here's the code of the extension content script main.js:
var webPort = chrome.runtime.connect();
var nativePort = null;
function sendNativeMessage(text) {
message = {"text": text};
nativePort.postMessage(message);
}
function onNativeMessage(message) {
webPort.postMessage({"type": "response", "text": message.text});
}
function onDisconnected() {
webPort.postMessage({"type": "connect-error", "text": chrome.runtime.lastError.message});
nativePort = null;
}
function connect() {
var hostName = "com.google.chrome.example.echo";
nativePort = chrome.runtime.connectNative(hostName);
nativePort.onMessage.addListener(onNativeMessage);
nativePort.onDisconnect.addListener(onDisconnected);
}
window.addEventListener("message", function(event) {
// We only accept messages from ourselves
if (event.source != window || !event.data.type) {
return;
}
console.log("Content script received message, type: " + event.data.type);
if (event.data.type === "connect") {
connect();
} else if (event.data.type === "send") {
sendNativeMessage(event.data.text);
}
}, false);
But, when I'm opening the web page, I'm getting two issues.
The code
chrome.runtime.connect()
raises an error:Could not establish connection. Receiving end does not exist.
The code
chrome.runtime.connectNative(hostName)
raises an error:Uncaught TypeError: chrome.runtime.connectNative is not a function.
What I am doing wrong?
The full code of the test project is here: https://github.com/h-mdm/test-chrome-ext
Subdirectories app and host contain a working example by Chrome. Subdirectories ext and web contain the extension example which is raising errors.