Avoiding LocalConnection's 40k size limit when data object may be larger than 40k

1.9k views Asked by At

Flash's LocalConnection mechanism has a 40k size limit on individual messages passed to send(). I'm running into a situation where I have a complex object that I need to send which may end up being too large.

I can break up the object into multiple smaller ones, but I want to do so in an efficient way. It's possible that I could end up with hundreds of smaller objects, and I don't want to have to send each one individually. Furthermore, each object could be of an arbitrary size, so I can't just pick some number to group them by.

Is there any way to determine the size of an object before passing it to send? If so I could use that to do some quick calculations and then break up the object somewhat optimally (or just send directly if it's small enough).

2

There are 2 answers

1
Herms On BEST ANSWER

I found a way to at least estimate the size of an object before sending it to LocalConnection by constructing a temporary SharedObject with the data. Since the SharedObject isn't ever written to the disk it seems to work even when local storage isn't allowed.

Here's the function I'm going to use to determine the size:

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

The messages I'm sending that are too big are arrays of complex objects. I'm going to assume no individual object will be too big (not 100% guaranteed, but most likely no user will put in enough data to make it big enough, and ignoring this case for now makes things much simpler). Given this assumption, I'll check the array before sending. If it's too big I'll split it in half and try those two arrays. I'll continue recursively splitting in half until I get to a set of arrays that are all small enough (Most likely I'll never need more than 1 split, but if I do then only 2 or 3).

Then each part of the array can be sent individually and recombined on the other end of the communication channel.

Here's the code I created to split an array into multiple arrays that are all small enough to send:

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);
}

I'm modifying my send code to call this on the potentially-too-big Array before it's sent, and then send each of the "split" arrays separately. Then in my receive code I'm recombining them and raising a single event with the combined data.

I'm keeping this updated for now (with documentation) here:

http://gist.github.com/224258

2
damian On

I'm not 100% sure, but this post on Ultrashock looks similar to what you need: http://www.ultrashock.com/forums/actionscript/40k-byte-size-limit-on-localconnection-56395.html

"If you need to send a large passage of text or an XML object as a string, you will quickly bump up against this ceiling. I thought I'd share a little modification to LocalConnection that lets you send practically limitless strings. It simply splits them up into as many "send" statements as necessary for them all to remain under 40K."

It would ensure that each segment sent was under the imposed limit without needing to know the size.