Родные сообщения Chrome: как получить> 1 МБ

Что может быть хорошим способом для работы с входящим лимитом Chrome в 1 МБ для собственных расширений обмена сообщениями? Данные, которые мы будем отправлять в расширение, это json-сериализованный gpx, если это имеет значение.

Когда исходное сообщение>1 МБ, кажется, что этот вопрос действительно состоит из двух частей:

  1. как разделить данные на отправляющей стороне (то есть клиенте)

    эта часть должна быть довольно тривиальной. Даже если нам нужно разбить на отдельные автономные полные строки gpx, это довольно просто.

  2. как присоединить сообщения <1MB обратно к оригиналу>1MB

    Есть ли стандартное решение для этого вопроса? Мы можем вызывать background.js (то есть функцию, переданную chrome.runtime.onMessageExternal.addListener) один раз для каждого входящего сообщения <1 МБ, но как бы мы соединили строки из этих повторных вызовов в один ответ для расширения?

ОБНОВЛЕНИЕ 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 ответ

У меня та же проблема, и я искал в Интернете последние пару дней, чтобы выяснить, чем заняться. В моем приложении в настоящее время я отправляю строку 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 будет выглядеть примерно так:

вар потоки;

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, который я мог бы найти, чтобы дать мне этот путь. Кроме того, есть папка 'version', созданная под вашим идентификатором расширения, которая содержит _0, который я не знаю, как рассчитать (является ли константа _0 для некоторого будущего использования? Она поднимается, когда расширение публикуется заново в интернет-магазине?, но версия не настроена?).

На данный момент у меня нет идей, и я надеюсь, что кто-нибудь натолкнется на этот вопрос с некоторым руководством.

Другие вопросы по тегам