简体   繁体   English

Chrome扩展程序的长期消息连接-如何使用回调函数?

[英]Chrome extension long-lived message connection - how to use callback functions?

For a while I've been using chrome.runtime.sendMessage(message, callback) for messages from my content script that need to run a callback function after receiving a response from the background. 一段时间以来,我一直在使用chrome.runtime.sendMessage(message, callback)处理来自内容脚本的chrome.runtime.sendMessage(message, callback)这些消息在收到来自后台的响应后需要运行回调函数。

I've also got a long-lived connection that is used for sending messages from the background to the content script (without it being a response to a message initiated by the content script): 我还拥有一个长期的连接,该连接用于将消息从后台发送到内容脚本(而不是对由内容脚本启动的消息的响应):

backgroundPort = chrome.runtime.connect({ name: "contentScript" });
backgroundPort.onMessage.addListener(function(message){
  if (message["action"] == "something"){
    // Do stuff
  }
});

As far as I can tell, backgroundPort.postMessage() does not support callback messages which means messages that have a callback need to use chrome.runtime.sendMessage() . 据我所知, backgroundPort.postMessage() 支持回调的消息,这意味着有回调需要使用的消息chrome.runtime.sendMessage()

The problem with this approach is that there is a lot of overhead in setting up a new connection between content script/background for each message, so I'm trying to get callback functionality into the existing long-lived connection through backgroundPort , but it gets kind of messy. 这种方法的问题在于,为每条消息在内容脚本/背景之间建立新的连接会产生大量开销,因此我试图通过backgroundPort将回调功能纳入现有的长期连接中,但是有点乱

Anyone who's been able to come up with an elegant solution? 有谁能够提出一个优雅的解决方案?

If you look at your background script as socket server (Port object is basically simulating sockets), you could use something called "acknowledgments" that is used in Nodejs, socket.io library. 如果将后台脚本视为套接字服务器(Port对象基本上是在模拟套接字),则可以使用Nodejs socket.io库中使用的称为“确认”的东西。

Basically you store your callbacks functions inside object by giving them unique identifier that you pass to the other side. 基本上,您通过为回调函数提供传递给另一端的唯一标识符来将它们存储在对象中。

// on the sending side

// this variable will store callbacks
var acknowledgments = {};

var port = chrome.runtime.connect();

// this variable will be unique callback idetifier
var address = Math.random().toString(36);

// You create acknowledgment by identifying callback
acknowledgments[address] = function (data) {
    // callback function
    // do what you like with result data
};

port.postMessage({
    acknowledgment: address,
    data: messageData
})

port.onMessage.addListener(function (message) {
    var callback = acknowledgments[message.acknowledgment];
    if (callback) {
        callback(message.data);
        // don't forget to unset acknowledgment, because it's 
        // supposed to exists only until it's been called.
        delete acknowledgments[message.acknowledgment];
        return;
    }

    // other message types handling
});

Other side passes result with that unique identifier returned, by which you an identify what to do. 另一方传递的结果带有返回的唯一标识符,您可以通过该标识符确定要执行的操作。

// on the listening side
chrome.runtime.onConnect.addListener(function (port) {
    port.onMessage.addListener(function (message) {
        if (message.acknowledgment) {
            // do stuff you need to do
            // then return result
            port.postMessage({
                acknowledgment: message.acknowledgment
                data: stuffYouHaveDoneResult
            });
        }
    });
});

chrome.runtime.sendMessage works using "Port" object at lower level so the actual implementation of sendMessage callback should be similar to this in principle. chrome.runtime.sendMessage在较低级别使用“ Port”对象,因此sendMessage回调的实际实现原则上应与此类似。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 React Base chrome 扩展中使用长寿命连接时无法获取状态值 - Unable to get state value in when using long-lived connection in react base chrome extension chrome扩展中具有长期连接的“尝试使用断开连接的端口对象” - “Attempting to use a disconnected port object” with Long-lived connections in chrome extension Chrome扩展程序的长期连接:从后台检索消息到内容 - Chrome extension long lived connection: retrieve message from background to content 如何建立与jQuery的长期连接以进行推送通知? - How can I establish a long-lived connection with jQuery for push notification? Facebook 图 API 长寿命令牌 - Facebook Graph API Long-Lived Token 将短期访问令牌交换为长期有效 - Exchange short-lived access token for long-lived, not working JavaScript最佳实践:如何实现长期存在的应用程序(单页Web应用程序)? - JavaScript Best Practices: How to implement long-lived apps (one-page web apps)? 如何在浏览器中获取JS代码的长期身份提供者令牌 - How to get long-lived indentity provider tokens for JS code in browser 使用Apache / PHP / Javascript的长期连接(异步服务器推送)? - Long-lived connections (asynchronous server push) with Apache/PHP/Javascript? Recoil:将长期存在的客户端 object 传递给选择器 - Recoil: Passing a long-lived client object to a selector
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM