connectNative在Chrome扩展程序中自行断开连接

时间:2014-07-16 07:49:18

标签: google-chrome-extension chrome-native-messaging

我确实写了一个chrome扩展名。我的内容脚本通过background.js发送一些数据。我的background.js shell将此数据转发到本地C ++应用程序。 现在发生的是,我的background.js可以连接到本地应用并发送一次数据。但是,当断开事件发生并且第二个发送请求失败时,连接将丢失。阅读connectNative的文档,它说,如果调用disconnect,则关闭连接,或者"当包含端口的页面被卸载时#34; 。我的代码中根本没有断开连接,background.js不应作为相应文档卸载background.js的实时时间与扩展的实时时间一样长。 使用我的代码,测试1和测试2在目标文件Test.txt中到达一次,但是第二次发送失败,因为两者之间的连接丢失。

这里的代码。

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 个答案:

答案 0 :(得分:2)

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

除此之外,以下内容看起来并不像#34;读取4个字符&#34;,但是&#34;读取3个字符&#34;。

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

即使将i <= 2更改为i < 4,这也只适用于最多255个字节的消息,因为您要对各个字节求和,而不是将四个字节解释为整数。我建议用以下内容替换上一段代码:

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

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