I did write a chrome extension. My content script send some data to by background.js
. And my background.js
shell forward this data to a local C++ app.
Now what happens is, my background.js
can connect to the local app and send data once. But then, the connection is lost as the disconnect event occurs and a second send request fails. Reading the documentation of connectNative it says, connection is closed, if the disconnect
is called or "when the page containing the port is unloaded". I don't have the disconnect at all in my code and the background.js
should not be unloaded as according documentation the livetime of background.js
is as long as livetime of the extension.
With my code, the Test 1 and Test 2 arrive once in the target file Test.txt
but send it a second time fails, as connection is lost in between.
Here the code.
background.js:
var port = null;
var firstTime;
function onNativeMessage(message) {
console.log("Native Message received: " + message);
}
function onDisconnected() {
console.log("Disconnected");
//port = null;
}
function connect() {
console.log("Connect");
//port = chrome.extension.connectNative('chromeinterface');
port = chrome.runtime.connectNative('chromeinterface');
port.onMessage.addListener(onNativeMessage);
port.onDisconnect.addListener(onDisconnected);
}
chrome.extension.onRequest.addListener(function(data, sender) {
if(firstTime !== 'xdefined') {
firstTime = 'xdefined';
connect();
}
port.postMessage("Test 1");
port.postMessage("Test 2");
console.log("Send");
}
});
manifest.json:
{
"name": "Test",
"version": "1.0",
"description": "Test native messaging",
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["contentscript.js"]
}
],
"permissions": ["tabs", "nativeMessaging", "<all_urls>"],
"manifest_version": 2
}
chromeinterface.json:
{
"name": "chromeinterface",
"description": "Chrome Native Messaging API Example Host",
"path": "chrome_interface",
"type": "stdio",
"allowed_origins": [
"chrome-extension://abc.../"
]
}
chrome_interface.cpp:
...
using namespace std;
void StoreData(string data)
{
ofstream File;
File.open("Test.txt", ios_base::out|ios_base::app);
if (File.is_open())
{
File << data;
File.close();
}
}
int main(int argc, char* argv[])
{
std::cout.setf( std::ios_base::unitbuf );
unsigned int a, c, i, t=0;
std::string inp;
bool bCommunicationEnds = false;
StoreData("Start " + inp + "\n");
cout << "Start" << endl;
do {
inp="";
t=0;
// Sum the first 4 chars from stdin (the length of the message passed).
for (i = 0; i <= 2; i++) {
t += getchar();
}
// Loop getchar to pull in the message until we reach the total
// length provided.
for (i=0; i < t; i++) {
c = getchar();
if(c == EOF)
{
bCommunicationEnds = true;
i = t;
}
else
{
inp += c;
}
}
StoreData("Received " + inp + "\n");
if(!bCommunicationEnds)
{
//Collect the length of the message
unsigned int len = inp.length();
//// We need to send the 4 btyes of length information
std::cout << char(((len>>0) & 0xFF))
<< char(((len>>8) & 0xFF))
<< char(((len>>16) & 0xFF))
<< char(((len>>24) & 0xFF));
//// Now we can output our message
std::cout << inp;
}
}while(!bCommunicationEnds);
StoreData("Com end\n");
return 0;
}
console.log:
Connect
Send
Disconnected
Error in event handler for extension.onRequest: Attempting to use a disconnected port object