[英]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.