google-chrome - chrome 原生消息 : how to receive > 1MB

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

什么是处理 Chrome 的本地消息扩展传入 1MB 限制的好方法?如果重要的话,我们将发送到扩展的数据是 json 序列化的 gpx。

当原始消息大于 1MB 时,这个问题似乎真的有两个部分:

  • 如何在发送端(即客户端)对数据进行分区

    这部分应该很简单。即使我们需要拆分成独立的完整 gpx 字符串,这也很简单。
  • 如何将 <1MB 消息加入到原始 >1MB

    这个问题有标准的已知解决方案吗?我们可以为每条 <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/

    相关文章:

    php - Chrome 将文件附件误解为文档

    javascript - 刷新页面和在 webkit 浏览器中输入页面有什么区别吗?(棘手)

    asp.net - Chrome 本地主机 cookie 未设置

    javascript - Google Docs - 以编程方式将鼠标点击发送到大纲 Pane 中的项目

    facebook-graph-api - 从没有服务器的桌面客户端进行 OAuth 的正确方法

    javascript - Chrome Native Messaging - 为什么我会收到 "Specified native messaging host not found"错误?

    css - 在网页上使用 Avant Garde BK BT 字体?

    java - 如何在java中实现chrome原生消息处理协议(protocol)

    c# - 如何让 Chrome Native Messaging 收听应用程序?

    javascript - 如何将消息从内容脚本发送到面板?