在Chrome扩展程序中,自行断开连接 [英] connectNative disconnects by itself in Chrome extension

查看:1201
本文介绍了在Chrome扩展程序中,自行断开连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这里的代码。

background.js:

  var port = null; 
var firstTime;

函数onNativeMessage(消息){
console.log(Native Message received:+ message);


function onDisconnected(){
console.log(Disconnected);
// port = null;


函数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 =' (Test 1);
port.postMessage(Test 2); $ b();
connect();
}

port.postMessage $ b console.log(Send);
}
});

manifest.json:

  {
name:Test,
version:1.0,
description:测试本机讯息,

background:{
scripts:[background.js]
},

content_scripts:[
{
matches:[< all_urls>],
js:[contentscript.js]
}
],

权限:[tabs,nativeMessaging,< all_urls>],

manifest_version:2
}
<


chromeinterface.json: name:chromeinterface,
description:Chrome原生消息API示例主机,
路径:chrome_interface,
type:stdio,
allowed_origins:[
chrome-extension://abc.../
]
}

chrome_interface.cpp:

  ... 
使用namespace std;

void StoreData(字符串数据)
{
ofstream File;
File.open(Test.txt,ios_base :: out | ios_base :: app);
if(File.is_open())
{
File<数据;
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 +\\\
);
cout<< 开始<< ENDL;

do {

inp =;
t = 0;
//总结前四个字符(消息传递的长度)。
for(i = 0; i <= 2; i ++){
t + = getchar();
}

//循环getchar来拉取消息,直到达到所提供的总
//长度。
for(i = 0; i< t; i ++){
c = getchar();
if(c == EOF)
{
bCommunicationEnds = true;
i = t;
}
else
{
inp + = c;
}
}
StoreData(Received+ inp +\\\
);

if(!bCommunicationEnds)
{
//收集消息的长度
unsigned int len = inp.length();
////我们需要发送4位长度信息
std :: cout<< char(((len>> 0)& 0xFF))
<< char(((len>> 8)& 0xFF))
<< char(((len>> 16)& 0xFF))
<< char(((len>> 24)& 0xFF));
////现在我们可以输出我们的消息
std :: cout<< INP;
}
} while(!bCommunicationEnds);

StoreData(Com end \\\
);

返回0;
}

console.log:

 连接
发送
断开连接
extension.onRequest的事件处理程序错误:尝试使用断开的端口对象

解决方案

删除 cout< < 开始<< endl; 来自您的代码。本地消息通过stdin和stdout进行通信。如果您在stdout中插入任何其他垃圾,则协议被违反,Chrome将终止本地应用程序。



除此之外,以下内容看起来不像read 4 chars,但是read 3 chars。


$ b

  //将前4个字符(消息传递的长度)。 
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并查看终端内的标准输出以获得更多有用的错误以进行调试本地应用程序。


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 

解决方案

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.

这篇关于在Chrome扩展程序中,自行断开连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆