Chrome扩展MV3: contentPort.onMessage优先于nativePort.onMessage服务工



我正在将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>
  • Manjaro Linux/gh>
  • Chromium 112.0.5615.49(官方版本)Arch Linux(64位)
  • 一台旧电脑(有些人称之为"土豆")
  • 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)))
    

    相关内容

    • 没有找到相关文章

    最新更新