connectNative disconnects by itself in Chrome extension

∥☆過路亽.° 提交于 2019-12-10 09:54:19

问题


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 

回答1:


Remove cout << "Start" << endl; from your code. Native messaging communicates via stdin and stdout. If you insert any other junk in stdout, then the protocol is violated and Chrome will terminate the native application.

Besides that, the following does not really look like "read 4 chars", but "read 3 chars".

    // Sum the first 4 chars from stdin (the length of the message passed).
    for (i = 0; i <= 2; i++) {
        t += getchar();
    }

Even after changing i <= 2 to i < 4, this will only work for messages up to 255 bytes because you're summing the individual bytes instead of interpreting the four bytes as an integer. I suggest to replace the previous snippet with:

    unsigned int t;
    std::cin.read(reinterpret_cast<char*>(&t), sizeof(t));

Start Chrome from the terminal and look in the standard output within the terminal to get more useful errors to debug native applications.



来源:https://stackoverflow.com/questions/24775096/connectnative-disconnects-by-itself-in-chrome-extension

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!