chrome native messaging:如何接收> 1MB

时间:2016-02-26 00:09:04

标签: google-chrome google-chrome-extension chrome-native-messaging

使用Chrome对本机邮件扩展的传入1MB限制有什么好办法?如果重要的话,我们将发送到扩展的数据是json-serialized gpx。

当原始邮件大于1MB时,似乎这个问题确实有两个部分:

  1. 如何对发送端(即客户端)上的数据进行分区

    这一部分应该是微不足道的。即使我们需要拆分成单独的自包含的完整gpx字符串,这也非常简单。

  2. 如何将< 1MB邮件重新加入原来的> 1MB

    这个问题有一个标准的已知解决方案吗?我们可以为每个< 1MB传入消息调用background.js(即传递给chrome.runtime.onMessageExternal.addListener的函数)一次,但是,我们如何将这些重复调用的字符串组合到一个响应中?

  3. 更新8-18-16: 我们一直在做的只是将每个消息'chunk'附加到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");
             });

    我们必须使附加功能更加智能,以处理和发送状态和消息键/值,但这应该很容易。

1 个答案:

答案 0 :(得分:0)

我有同样的问题,并且在过去的几天里一直在搜索网络以找出要做的事情。在我的应用程序中,我目前正在以块的形式将JSON字符串传送到后台脚本,必须创建一个子协议来处理这种特殊情况。例如我最初的问题可能如下:

{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}

并在收到方法==='stream'的有效载荷后,后台页面将立即发出新的请求,如:

{action:"getStream",guid:"123"}

,下一个响应可能如下:

{action:"getStream",guid:"123",status:"success",return:"...DEAF==",more:false}

所以你的onMessage处理程序看起来像:

var streams;

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信号的缓慢感觉,并且在我的特定应用中,每个新块必须发生的额外信号)。

理想情况下,我希望使用Chrome本身支持的更高效协议来传输文件。我查看了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;
}

我有我的本机消息主机将.json文件写入扩展的安装目录并且它似乎工作,但是我无法可靠地获取路径(没有捏造东西并希望最好),因为我可以根据您的Chrome用户个人资料确定扩展程序安装路径的位置,并且我找不到可以找到该API的API。另外,在你的扩展名id下创建了一个“版本”文件夹,其中包含一个我不知道如何计算的_0(将来是否会使用_0常量?当扩展重新发布到网上商店时,它会加剧吗? ,但版本没有调整?)。

在这一点上,我没有想法,我希望有人会在一些指导下偶然发现这个问题。