Как избежать ограничения размера LocalConnection в 40 КБ, если размер объекта данных может превышать 40 КБ - PullRequest
3 голосов
/ 28 октября 2009

Механизм LocalConnection Flash имеет ограничение в 40 КБ для отдельных сообщений, передаваемых на send(). Я сталкиваюсь с ситуацией, когда мне нужно отправить сложный объект, который может оказаться слишком большим.

Я могу разбить объект на несколько меньших, но я хочу сделать это эффективным способом. Вполне возможно, что я смогу получить сотни небольших объектов, и я не хочу отправлять каждый из них по отдельности. Кроме того, каждый объект может иметь произвольный размер, поэтому я не могу просто выбрать какое-то число, чтобы сгруппировать их.

Есть ли способ определить размер объекта перед его передачей для отправки? Если это так, я мог бы использовать это для некоторых быстрых вычислений, а затем несколько оптимально разбить объект (или просто отправить напрямую, если он достаточно мал).

Ответы [ 2 ]

1 голос
/ 02 ноября 2009

Я нашел способ как минимум оценить размер объекта перед отправкой его в LocalConnection, создав временный объект SharedObject с данными. Поскольку SharedObject никогда не записывается на диск, похоже, он работает, даже когда локальное хранилище не разрешено.

Вот функция, которую я собираюсь использовать для определения размера:

public static function getObjectSize(o:Object):Number {
  var so:SharedObject = SharedObject.getLocal("__getObjectSizeHelper");
  so.data.o = o;
  var size:Number = so.getSize();
  so.clear();
  return size;
}

Слишком большие сообщения, которые я отправляю, являются массивами сложных объектов. Я собираюсь предположить, что ни один отдельный объект не будет слишком большим (не гарантировано на 100%, но, скорее всего, ни один пользователь не введет достаточно данных, чтобы сделать его достаточно большим, и игнорирование этого случая пока делает вещи намного проще). Учитывая это предположение, я проверю массив перед отправкой. Если он будет слишком большим, я разделю его пополам и попробую эти два массива. Я буду продолжать рекурсивное разбиение пополам до тех пор, пока не доберусь до набора массивов, которые все достаточно малы (скорее всего, мне никогда не понадобится более 1 разбиения, но если я сделаю это, то только 2 или 3).

Затем каждая часть массива может быть отправлена ​​индивидуально и рекомбинирована на другом конце канала связи.

Вот код, который я создал, чтобы разбить массив на несколько массивов, достаточно маленьких для отправки:

public static function isTooBigForLC(o:Object):Boolean {
  return getObjectSize(o) > 35000;
}

public static function splitArrayForLC(a:Array):Array {
  if (!isTooBigForLC(a)) { return [a]; }

  if (a.length <= 1) {
    LOG.warn("individual object is too big for LocalConnection! Skipping");
    return [];
  }

  var mid:Number = Math.floor(a.length / 2);

  var left:Array = splitArrayForLC(a.slice(0, mid));
  var right:Array = splitArrayForLC(a.slice(mid));

  return left.concat(right);
}

Я изменяю свой код отправки, чтобы вызывать его для потенциально слишком большого массива перед его отправкой, а затем отправляю каждый из «разделенных» массивов отдельно. Затем в своем коде получения я рекомбинирую их и вырабатываю одно событие с объединенными данными.

Сейчас я держу это обновление (с документацией) здесь:

http://gist.github.com/224258

0 голосов
/ 30 октября 2009

Я не уверен на 100%, но этот пост на Ultrashock выглядит примерно так, как вам нужно: http://www.ultrashock.com/forums/actionscript/40k-byte-size-limit-on-localconnection-56395.html

«Если вам нужно отправить большой отрывок текст или объект XML в виде строки, вы быстро столкнется с этим потолок. Я думал, что поделюсь немного модификация LocalConnection, которая позволяет отправлять практически безгранично строки. Это просто разбивает их на столько «отправить» заявления, сколько необходимо чтобы они все остались под 40К ".

Это обеспечит, чтобы каждый отправленный сегмент находился под наложенным лимитом без необходимости знать размер.

...