我正在使用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;
}
请注意,我从this问题找到了上述方法。
目前,我只是想将字符串写入.txt文件:
public void Main(String[] args) {
string msg = OpenStandardStreamIn();
System.IO.File.WriteAllText(@"path_to_file.txt", msg);
}
我只是通过下载文件来测试我的getDOM.js
功能,整个过程几乎是即时的。
我不确定为什么这个过程需要这么长时间,为什么文件太大,或者为什么几乎没有任何消息实际发送。
我不确定这是否与以特定方式反序列化消息有关,如果我应该创建一个端口而不是使用chrome.runtime.sendNativeMessage(...);
方法,或者如果我还有别的东西我是丢失。
非常感谢所有帮助!谢谢!
修改
虽然我的消息正确地从扩展程序发送到主机,但我现在在扩展程序接收主机消息之前收到Native host has exited error
。
答案 0 :(得分:2)
这个问题基本上是在询问, “我如何才能有效,快速地从标准输入中读取信息?”
在上面的代码中,问题不在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
。