问题描述
如何使用Chrome的本机消息扩展名的传入限制限制为1MB?如果需要的话,我们将发送给扩展程序的数据是json序列化的gpx.
What would be a good way to work with Chrome's incoming 1MB limit for native messaging extensions? The data that we would be sending to the extension is json-serialized gpx, if that matters.
当原始消息为> 1MB时,似乎此问题确实包含两个部分:
When the original message is >1MB, it seems like this question really has two parts:
-
如何在发送端(即客户端)上对数据进行分区
how to partition the data on the sending end (i.e. the client)
这部分应该很简单.即使我们需要分割成独立的完整gpx字符串,这也非常简单.
this part should be pretty trivial. Even if we need to split into separate self-contained complete gpx strings, that is pretty straightforward.
如何将< 1MB邮件重新加入到原始的> 1MB
how to join the <1MB messages back in to the original >1MB
此问题是否有标准的已知解决方案?我们可以为每个< 1MB的传入消息调用一次background.js(即传递给chrome.runtime.onMessageExternal.addListener的函数),但是,如何将这些重复调用中的字符串组合到扩展的一个响应中呢?
is there a standard known solution for this question? We can call background.js (ie. the function passed to chrome.runtime.onMessageExternal.addListener) once for each <1MB incoming message, but, how would we combine the strings from those repeated calls in to one response for the extension?
更新8-18-16:我们一直在做的只是将每条消息块"附加到background.js的缓冲区变量中,直到断开连接后才将其发送回Chrome:
UPDATE 8-18-16:what we've been doing is just appending each message 'chunk' on a buffer variable in background.js, and not send it back to Chrome until disconnection:
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");
});
我们必须使附加操作更聪明,以便处理和发送状态键和消息键/值,但这应该很容易.
We will have to make that appending a bit smarter to handle and send both status and message keys/values, but that should be easy.
推荐答案
我也遇到了同样的问题,并且在过去的几天里一直在网上搜索以寻找解决办法.在我的应用程序中,我目前正在将JSON字符串分批发送到后台脚本,必须创建一个子协议来处理这种特殊情况.例如我最初的问题可能是这样的:
I have this same issue and have been scouring the web for the past couple days to figure out something to do. In my application, I am currently shipping a JSON string over to the background script in chunks, having to create a subprotocol to handle this special case. e.g. my initial question might look like:
{action:"getImage",guid:"123"}
,对于< 1MB的响应可能如下所示:
and the response for <1MB might look like:
{action:"getImage",guid:"123",status:"success",return:"ABBA..."}
其中ABBA ...表示字节的base64编码.但是,当> 1MB时,响应将如下所示:
where ABBA... represents a base64 encoding of the bytes. when >1MB, however, the response will look like:
{action:"getStream",guid:"123",status:"success",return:"{action:\"getImage\",guid:\"123\",return:\"ABBA...",more:true}
,并且在使用method ==='stream'接收到有效负载后,后台页面将立即发出新请求,例如:
and upon receipt of the payload with method==='stream', the background page will immediately issue a new request like:
{action:"getStream",guid:"123"}
,下一个响应可能类似于:
and the next response might look like:
{action:"getStream",guid:"123",status:"success",return:"...DEAF==",more:false}
因此您的onMessage处理程序将类似于:
so your onMessage handler would look something like:
var个流;
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信号的感觉很慢,在我的特定应用中,每个新块都必须发生其他信号)).
it works, but I am somewhat convinced that it is slower than it should be (though this could be due to the slow feeling of the STDIO signaling and, in my particular app, additional signaling that has to happen for each new chunk).
理想情况下,我想以Chrome原生支持的更有效协议流式传输文件.我研究了WebRTC,但这意味着我需要在本机消息传递主机中实现API(据我所知),这不是我愿意采取的选择.我按这样通过文件传递"了内容:
Ideally I'd like to stream the file in a more efficient protocol supported natively by Chrome. I looked into WebRTC, but it would mean that I'd need to implement the API into my native messaging host (as best I can tell), which is not an option I'm willing to take on. I played with 'passing' the contents by file as such:
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;
}
我的本地消息主机在其中将.json文件写到扩展程序的安装目录中,并且似乎可以正常工作,但是我无法可靠地导出路径(不进行任何伪造并希望获得最好的路径),因为尽我所能,扩展程序安装路径的位置由您的Chrome用户个人资料确定,并且找不到可以给我该路径的API.此外,在您的扩展程序ID下创建了一个版本"文件夹,其中包含一个我不知道如何计算的_0(_0常量是否可以在将来使用?在扩展程序重新发布到网上商店时,它会打勾吗?,但版本未调整?).
where I have my native message host write a .json file out to extension's install directory and it seems to work, but there is no way for me to reliably derive the path (without fudging things and hoping for the best), because as best I can the location of the extensions install path is determined by your Chrome user profile and there's no API I could find to give me that path. Additionally, there's a 'version' folder created under your extension id which includes an _0 that I don't know how to calculate (is the _0 constant for some future use? does it tick up when an extension is published anew to the web store, but the version is not adjusted?).
在这一点上,我没有想法,我希望有人能在一些指导下偶然发现这个问题.
At this point I'm out of ideas and I'm hoping someone will stumble across this question with some guidance.
这篇关于chrome本机消息传递:如何接收>1MB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!