什么是处理 Chrome 的本地消息扩展传入 1MB 限制的好方法?如果重要的话,我们将发送到扩展的数据是 json 序列化的 gpx。
当原始消息大于 1MB 时,这个问题似乎真的有两个部分:
这部分应该很简单。即使我们需要拆分成独立的完整 gpx 字符串,这也很简单。
这个问题有标准的已知解决方案吗?我们可以为每条 <1MB 的传入消息调用一次 background.js(即传递给 chrome.runtime.onMessageExternal.addListener 的函数),但是,我们如何将来自这些重复调用的字符串组合成一个扩展响应?
16 年 8 月 18 日更新:
我们一直在做的只是将每条消息“ block ”附加到 background.js 中的缓冲区变量上,直到断开连接才将其发送回 Chrome:
var gpxText="";
port.onMessage.addListener(function(msg) {
// msg must be a JSON-serialized simple string;
// append each incoming msg to the collective gpxText string
// but do not send it to Chrome until disconnection
// console.log("received " + msg);
gpxText+=msg;
});
port.onDisconnect.addListener(function(msg) {
if (gpxText!="") {
sendResponse(JSON.parse(gpxText));
gpxText="";
} else {
sendResponse({status: 'error', message: 'something really bad happened'});
}
// build the response object here with msg, status, error tokens, and always send it
console.log("disconnected");
});
我们将不得不使附加更智能以处理和发送状态和消息键/值,但这应该很容易。
最佳答案
我有同样的问题,并且在过去的几天里一直在网上搜索以找出要做的事情。在我的应用程序中,我目前正在将 JSON 字符串分 block 发送到后台脚本,必须创建一个子协议(protocol)来处理这种特殊情况。例如我最初的问题可能如下所示:
{action:"getImage",guid:"123"}
<1MB 的响应可能如下所示:
{action:"getImage",guid:"123",status:"success",return:"ABBA..."}
其中 ABBA... 表示字节的 base64 编码。但是,当 >1MB 时,响应将如下所示:
{action:"getStream",guid:"123",status:"success",return:"{action:\"getImage\",guid:\"123\",return:\"ABBA...",more:true}
并且在收到带有 method==='stream' 的有效负载后,后台页面将立即发出一个新请求,例如:
{action:"getStream",guid:"123"}
下一个响应可能如下所示:
{action:"getStream",guid:"123",status:"success",return:"...DEAF==",more:false}
所以你的 onMessage 处理程序看起来像:
变量流;
function onMessage( e ) {
var guid = e.guid;
if ( e.action === 'getStream' ) {
if ( !streams[ guid ] ) streams[ guid ] = '';
streams[ guid ] += e[ 'return' ];
if ( e.more ) {
postMessage( { action: 'getStream', guid: guid } );
// no more processing to do here, bail
return;
}
e = JSON.parse( streams[ guid ] );
streams[ guid ] = null;
}
// do something with e as if it was never chunked
...
}
它有效,但我有点相信它比它应该的要慢(尽管这可能是由于 STDIO 信号的缓慢感觉,并且在我的特定应用程序中,每个新 block 都必须发生额外的信号)。
理想情况下,我希望以 Chrome 原生支持的更高效协议(protocol)流式传输文件。我研究了 WebRTC,但这意味着我需要在我的本地消息传递主机中实现 API(据我所知),这不是我愿意接受的选项。我玩了这样的文件“传递”内容:
if ( e.action = 'getFile' ) {
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function( e ) {
if ( e.target.readyState === 4 ) {
onMessage( e.target.responseText );
}
};
xhr.open( 'GET', chrome.extension.getURL( '/' + e.file ), true );
xhr.send();
return;
}
我让我的 native 消息主机将一个 .json 文件写入扩展程序的安装目录,它似乎可以工作,但我无法可靠地导出路径(没有捏造东西并希望最好),因为最好我扩展安装路径的位置是否由您的 Chrome 用户配置文件确定,并且我找不到任何 API 可以为我提供该路径。此外,在您的扩展程序 ID 下创建了一个“版本”文件夹,其中包含一个我不知道如何计算的 _0(_0 是否为将来使用的常量?当扩展程序重新发布到网络商店时它会打勾吗? ,但版本没有调整?)。
在这一点上,我没有想法,我希望有人会在一些指导下偶然发现这个问题。
关于google-chrome - chrome 原生消息 : how to receive > 1MB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35640924/