views:

315

answers:

3

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).

A: 

i would prefer to use ExternalInterface

see for a example: adobe example

or google it you will find a lot of tutorials...

it helps me a couple of times.

michel
ExternalInterface would allow me to communicate with javascript, but I'd have to build a javscript communication bridge for it to work SWF to SWF. And that's not really feasible, especially since we've already seen reliability problems with a javascript communication bridge used elsewhere. Plus, this is a pre-existing application with heavy use of LocalConnection, so it wouldn't be feasible to change it.
Herms
A: 

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.

mindshare
Sadly I'm dealing with complex objects, not just strings. But I'm looking at a solution along similar lines (just can't see a way to make it a generic implementation).
Herms
+1  A: 

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

Herms
This seems to be working well for me, and since it's the only answer here that was usable for me I'm going to mark it as the accepted one.
Herms