3

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 
4

1 回答 1

2

cout << "Start" << endl;从您的代码中删除。本机消息通过标准输入和标准输出进行通信。如果您在标准输出中插入任何其他垃圾,则违反协议,Chrome 将终止本机应用程序。

除此之外,以下看起来并不像“读取 4 个字符”,而是“读取 3 个字符”。

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

即使更改i <= 2i < 4,这也仅适用于最多 255 个字节的消息,因为您将各个字节相加,而不是将四个字节解释为整数。我建议将前面的代码段替换为:

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

从终端启动 Chrome 并查看终端内的标准输出,以获得更多有用的错误来调试本机应用程序。

于 2014-07-16T09:45:58.017 回答