将“大量”数据从Chrome扩展程序传递到主机(用C#编写)非常慢

本文关键字:主机 编写 非常 大量 数据 程序 扩展 Chrome | 更新日期: 2023-09-27 18:35:22

我正在使用Chrome的本机消息传递API将页面的DOM传递给我的主机。当我尝试将一个小字符串从我的扩展传递给我的主机时,一切正常,但是当我尝试传递整个 DOM(不是那么大......只有大约 260KB),一切都运行得慢得多,我最终得到了一个阻止主机响应Native host has exited error

我的主要问题:为什么将 250KB - 350KB 的消息从扩展传递到主机需要这么长时间?

根据开发商的网站:

Chrome 会在单独的进程中启动每个原生消息传递主机,并使用标准输入 (stdin) 和标准输出 (stdout) 与其通信。相同的格式用于双向发送消息:每条消息都使用 JSON 和 UTF-8 编码进行序列化,并在前面按本机字节顺序排列 32 位消息长度。来自本机消息传递主机的单封邮件的最大大小为 1 MB,主要是为了保护 Chrome 免受行为异常的本机应用程序的侵害。发送到本机消息传递主机的消息的最大大小为 4 GB。

我有兴趣发送给主机的页面的 DOM 不超过 260KB(有时为 300KB),远低于强加的 4GB 最大值。

弹出窗口.js

document.addEventListener('DOMContentLoaded', function() {
    var downloadButton = document.getElementById('download_button');
    downloadButton.addEventListener('click', function() {
        chrome.tabs.query({currentWindow: true, active: true}, function (tabs) {
            chrome.tabs.executeScript(tabs[0].id, {file: "getDOM.js"}, function (data) {
                chrome.runtime.sendNativeMessage('com.google.example', {"text":data[0]}, function (response) {
                    if (chrome.runtime.lastError) {
                        console.log("Error: " + chrome.runtime.lastError.message);
                    } else {
                        console.log("Response: " + response);
                    }
                });
            });
        });
    });
});

主机.exe

private static string StandardOutputStreamIn() {
    Stream stdin = new Console.OpenStandardInput();
    int length = 0;
    byte[] bytes = new byte[4];
    stdin.Read(bytes, 0, 4);
    length = System.BitConverter.ToInt32(bytes, 0);
    string = "";
    for (int i=0; i < length; i++)
        string += (char)stdin.ReadByte();
    return string;
}

请注意,我从这个问题中找到了上述方法。

目前,我只是尝试将字符串写入.txt文件:

public void Main(String[] args) {
    string msg = OpenStandardStreamIn();
    System.IO.File.WriteAllText(@"path_to_file.txt", msg);
}
  1. 将字符串写入文件需要很长时间(~4 秒,有时长达 10 秒)。
  2. 实际写入的文本量各不相同,但绝非是顶部文档声明和一些 IE 注释标记。现在显示所有文本。
  3. 这个几乎没有任何文本的文件是 649KB,但实际文档应该只有 205KB(当我下载它时)。该文件仍然比应有的稍大(216KB,而应该是 205KB)。

我已经通过下载文件来测试我的getDOM.js功能,整个过程几乎是即时的。

我不确定为什么这个过程需要这么长时间,为什么文件如此之大,或者为什么几乎没有任何消息实际发送。

我不确定这是否与以特定方式反序列化消息有关,我是否应该创建一个端口而不是使用 chrome.runtime.sendNativeMessage(...); 方法,或者我是否完全缺少其他东西。

非常感谢所有的帮助!谢谢!


编辑

尽管我的消息正确地从扩展发送到主机,但我现在在扩展接收主机消息之前收到Native host has exited error

将“大量”数据从Chrome扩展程序传递到主机(用C#编写)非常慢

这个问题本质上是在问:"如何高效快速地从标准输入中读取信息?

在上面的代码中,问题不在于Chrome扩展程序和主机之间,而在于标准输入和从标准输入流中读取的方法(即StandardOutputStreamIn()

该方法在OP代码中的工作方式是循环运行标准输入流,并连续地将input字符串与新字符串(即它从字节流中读取的字符)连接起来。这是一个昂贵的操作,我们可以通过创建一个StreamReader对象来一次抓取整个流来解决这个问题(特别是因为我们知道前 4 个字节中包含的长度信息)。因此,我们通过以下方式解决了速度问题:

    public static string OpenStandardStreamIn()
    {
        //Read 4 bytes of length information
        System.IO.Stream stdin = Console.OpenStandardInput();
        int length = 0;
        byte[] bytes = new byte[4];
        stdin.Read(bytes, 0, 4);
        length = System.BitConverter.ToInt32(bytes, 0);
        char[] buffer = new char[length];
        using (System.IO.StreamReader sr = new System.IO.StreamReader(stdin))
        {
            while (sr.Peek() >= 0)
            {
                sr.Read(buffer, 0, buffer.Length);
            }
        }
        string input = new string(buffer);
        return input;
    }

虽然这解决了速度问题,但我不确定为什么扩展会抛出Native host has exited error