我正在将MV2扩展迁移到MV3,并且作为该过程的一部分显然切换到后台服务工作者。
我的内容脚本使用以下API连接到后台service worker,然后在端口上设置一些侦听器。
this.port = chrome.runtime.connect({name: CONTENT_BG_PROXY_CONNECTION_NAME});
在service worker中,我注册为侦听此连接,并响应侦听该端口上的消息。然后,我还创建了本机消息传递主机连接,并侦听该端口上的消息(除了一些我认为无关紧要的额外业务逻辑
)。chrome.runtime.onConnect.addListener(function(port) {
if(port.name == CONTENT_BG_PROXY_CONNECTION_NAME) {
let contentPort = port;
let nativePort = chrome.runtime.connectNative(NATIVE_MESSAGING_APP_NAME);
nativePort.onMessage.addListener(function(message) {
//...
contentPort.postMessage(message);
});
contentPort.onMessage.addListener(function(message) {
//...
nativePort.postMessage(message);
});
}
});
问题是,如果内容脚本发送大量消息-最坏的情况下可能每秒60 -然后contentPort。onMessage回调被持续触发,但是来自本机主机的响应没有被作为nativePort处理。onMessage未被触发
一旦我停止内容脚本发送消息,突然所有那些挂起的响应开始在nativePort.onMessage中处理。
我确定我可以做一些速率限制或其他事情,但这种情况与MV2完美配合。处理过程似乎在事件处理程序之间被分割。
是否有一种方法可以给这些事件处理程序同等的优先级,或者实际上给从本机返回的消息更高的优先级?
我无法重现这个问题。
<<ul>manifest.json
{
"manifest_version": 3,
"name": "port_background_native_simple",
"version": "0.0.1",
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["content_script.js"]
}
],
"background": {
"service_worker": "background.js"
},
"action": {
},
"permissions": [
"nativeMessaging"
]
}
background.js
let message_counter = 1;
chrome.runtime.onConnect.addListener(function(port) {
if(port.name == "port_background_native_simple") {
let contentPort = port;
let nativePort = chrome.runtime.connectNative("port_background_native_simple");
nativePort.onMessage.addListener(function(message) {
console.log("nativePort.onMessage", message + " / " + message_counter);
contentPort.postMessage(message);
message_counter++;
});
contentPort.onMessage.addListener(function(message) {
console.log("contentPort.onMessage", message + " / " + message_counter);
nativePort.postMessage(message);
});
}
});
content_script.js
this.port = chrome.runtime.connect({name: "port_background_native_simple"});
setInterval(() => {
this.port.postMessage("test message");
}, Math.round(1000 / 60));
port_background_native_simple.py
#!/usr/bin/python -u
# Note that running python with the `-u` flag is required on Windows,
# in order to ensure that stdin and stdout are opened in binary, rather
# than text, mode.
import os
import json
import sys
import struct
import psutil
# Read a message from stdin and decode it.
def get_message():
raw_length = sys.stdin.buffer.read(4)
if not raw_length:
sys.exit(0)
message_length = struct.unpack("=I", raw_length)[0]
message = sys.stdin.buffer.read(message_length).decode("utf-8")
return json.loads(message)
# Encode a message for transmission, given its content.
def encode_message(message_content):
encoded_content = json.dumps(message_content).encode("utf-8")
encoded_length = struct.pack("=I", len(encoded_content))
# use struct.pack("10s", bytes), to pack a string of the length of 10 characters
return {"length": encoded_length, "content": struct.pack(str(len(encoded_content))+"s",encoded_content)}
# Send an encoded message to stdout.
def send_message(encoded_message):
sys.stdout.buffer.write(encoded_message["length"])
sys.stdout.buffer.write(encoded_message["content"])
sys.stdout.buffer.flush()
try:
while True:
message = get_message()
sys.stderr.write(message + "n")
send_message(encode_message(message))
except Exception as e:
send_message(encode_message(str(e)))