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

我正在使用Chrome的Native Messaging 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的最大值。

popup.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); } }); }); }); }); }); 

host.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(当我下载它)。 该文件仍然比它应该稍大(当它应该是205KB时216KB)。

我只是通过下载文件来测试我的getDOM.js函数,整个过程几乎是瞬间完成的。

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

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

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


编辑

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

这个问题基本上是在问: “我怎样才能有效,快速地从标准输入中读取信息?”

在上面的代码中,问题不在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