Google chrome extension 如何使用runtime.connect从background.js向所有内容脚本发送消息

Google chrome extension 如何使用runtime.connect从background.js向所有内容脚本发送消息,google-chrome-extension,Google Chrome Extension,如何使用runtime.connect和从background.js向所有内容脚本发送消息 用于长寿命连接的postMessage chrome文档说明了这一点 chrome.runtime.onConnect.addListener(function(port) { console.assert(port.name == "knockknock"); port.onMessage.addListener(function(msg) { if (msg.joke == "Knoc

如何使用runtime.connect和从background.js向所有内容脚本发送消息 用于长寿命连接的postMessage

chrome文档说明了这一点

chrome.runtime.onConnect.addListener(function(port) {
  console.assert(port.name == "knockknock");
  port.onMessage.addListener(function(msg) {
    if (msg.joke == "Knock knock")
      port.postMessage({question: "Who's there?"});
    else if (msg.answer == "Madame")
      port.postMessage({question: "Madame who?"});
    else if (msg.answer == "Madame... Bovary")
      port.postMessage({question: "I don't get it."});
  });
});
它会向所有内容发送消息吗?
我在某个地方读到,所有内容脚本都通过唯一的端口连接到扩展,我只是对如何向所有内容脚本发送消息感到困惑,正如devnull69在评论中提到的,要向所有已打开的端口发送消息,您需要跟踪它们

但是使用数组会有点问题。如何删除断开连接的端口

我发现这个问题很有趣,并编写了以下代码:

var openPorts=(函数(){
var指数=0;
var端口={};
var op={
getPorts:function(){
var result={};
for(端口中的变量id){
结果[id]=端口[id];
}
返回结果;
},
getPortsArray:function(){
var结果=[];
for(端口中的变量id){
结果.推送(端口[id]);
}
返回结果;
},
获取:函数(id){
返回端口[id];
},
添加:功能(端口){
var id=指数;
端口[id]=端口;
port.onDisconnect.addListener(函数(){
op.remove(id);
});
索引++;
返回id;
},
删除:函数(id){
删除端口[id];
},
messageAll:函数(message){
for(端口中的变量id){
端口[id]。postMessage(消息);
}
}
};
返回op;
})();
这是一个对象,它可以使用增量ID存储端口,如数组的push,一旦触发了
onDisconnect
,就会自动从中删除端口

您可能会多次添加端口,所有方法都将返回重复的端口,但同一端口的所有记录都将被删除,因为
onDisconnect
事件将调用所有删除侦听器。不过最好保持记录的唯一性

  • openPorts.add(port)
    -用于添加端口的函数将返回其记录id 内部
    openPorts
  • openPorts.get(id)
    -通过记录id获取端口对象的函数
  • openPorts.remove(id)
    -通过id手动删除端口记录的函数;不会关闭该端口
  • openPorts.getPorts()
    -按记录id返回包含所有打开端口的对象
  • openPorts.getPortsArray()
    -如果希望在所有打开的端口上迭代,则返回一个包含所有打开端口的数组
  • openPorts.messageAll(message)
    -向
    openPorts
用法示例:

chrome.runtime.onConnect.addListener(函数(端口){openPorts.add(端口);});
// ...
messageAll({hello:“world”});

您的示例将向之前发送消息的(一)个内容脚本发送响应消息。如果所有内容脚本都连接到background.js(甚至通过不同的端口),然后发送消息,background.js应该响应所有这些内容脚本。但是(当然)使用相同的
postMessage
方法不会发生这种情况,每个内容脚本都会收到自己的响应。那么如何将消息发送到所有内容脚本?我应该为内容脚本维护端口阵列并使用for循环发送还是有一些简单的方法?是的,您应该维护一个开放端口阵列