A few months ago I built a class that makes establishing two way communication between SWFs via LocalConnection much easier. This is useful for talking between different SWFs embedded on the same HTML page, but especially for communicating between an ActionScript 3 application SWF, and loaded ActionScript 2 content SWFs.
It's fairly easy to use, just create a SWFBridge instance inside each SWF with a shared id:
// in the AS2 SWF: var myBridge:SWFBridgeAS2 = new SWFBridgeAS2("connectionID", clientObj); // in the AS3 SWF: var myBridge:SWFBridgeAS3 = new SWFBridgeAS3("connectionID", clientObj);The SWFBridge system will automatically negotiate a two way connection between the two instances. The nice thing is, you don't need to wait for your content to be loaded to instantiate your bridge – it will set itself up as a host, and wait for another bridge instance to connect to it. Now you simply call "send" on either SWFBridge instance to call a method on the clientObj of the other instance.
// for example, calling this in the AS2 SWF: myBridge.send("myMethod", "Hello", "World"); // would result in this method call in the AS3 SWF: clientObj.myMethod("Hello", "World")When you're ready to unload your SWF, it's usually a good idea to close the connection to free up the LocalConnection name.
myBridge.close();
You can also check the status of your connection, and receive an event when the connection is established.
if (myBridge.connected) { ... do something ... } myBridge.addEventListener(Event.CONNECT, handleConnect);Here's a very simple (and ugly) demo of the system in action. It shows an AS3 SWF (top) communicating with a loaded AS2 SWF (bottom) through SWFBridge. Hopefully this is useful to someone. I planned to release it sooner, but never got around to it. Let me know in the comments if you encounter any issues. Flash CS3 is required to open the included demo FLAs, but these classes will work fine in Flex 2 or 3 as well. You can download it by clicking here.
Comments (51)
This is great, one less thing I have to write / deal with! Thanks!
Posted by: Paul at July 30, 2007 09:19 PMURL: http://www.actionscriptarchitect.com
I have been struggling with this concept for a couple days so I was happy to see this.
Unfortunately I've not been able to get it to work within a Flex Builder 3-based AIR application on Mac OS X. However, I can't get any LocalConnection stuff working between ActionScript 2 in a SWFLoader and the parent ActionScript 3.
Are there any simple recommendations you can give me or things I should be looking for to explain why I am unable to get this to work?
Posted by: Edward Mansouri at July 30, 2007 10:49 PMURL: http://www.airapps.net
Sincerely, I'm just stupefied since we've just released a product somehow similar to your SWF Bridge, but it may be easier to use and integrate since it is a drag&drop component, it is called ASB (ActionScript Bridge) and it consists of 2 components that enables AS2 and AS3 to communicate and interact within the same AS3.0 project.
It uses of course.. the LocalConnection, but it manages to create channels of communication without the need to code and manually create connections. Also you can run actions with the implemented API.
The ASB API consists of easy to use methods and 2 flash components:
1. ASBTerminal (the drag and drop ASB terminal/connector for AS2.0, enables any AS2.0 swf files for AS3.0 integration and communication).
2. ASBContainer (the loader/container that is used in AS3.0 projects to include ASB enabled AS2.0 files, using the source parameter)
if you want to read more about this, here is the link, it is FREE for all, our first free product
Posted by: jumpeyecomponents at July 31, 2007 06:53 AMhttp://www.jumpeyecomponents.com/Flash-Components/Various/ActionScript-Bridge-91/
URL: http://www.jumpeyecomponents.com
@jumpeyecomponents
Some people don't like to use components. I'd VERYYYYYY much, a million times much, feel more comfortable creating an instance of the class and using it that way.
All my AS3.0 stuff is class based, so i'd personally have no use for a component and find that the 'black box' idea of components in that case would just hinder my development.
Still everyone likes their own ways of doing things, so that's just me.
Posted by: mario gonzalez at July 31, 2007 09:55 AMURL: http://onedayitwillmake.com
I get a runtime error when I open this page again in a second browser window - connection already opened.
I just tried this because that's an easy way to break most local connections. There also used to be an issue where sometimes on refresh the connection doesn't get cleared fast enough, and it fails to establish.
The workaround (solution) we've been using is to create a unique session id in the HTML (new Date().getTime()), and use it in all LC's that are supposed to connect.
Posted by: Andreas Heim at July 31, 2007 11:45 AMURL: http://www.smashingideas.com
Andreas,
Good point to raise. I considered writing something that dealt with this automatically, but chose to keep it open so that developers can implement different approaches to the problem (for example, your unique id approach might make sense for some projects, whereas in others I would want to catch the error and show a dialog).
Cheers.
Posted by: Grant Skinner at July 31, 2007 11:48 AMURL: http://gskinner.com/blog/
The unique ID problem that you have when using 2 or more windows is related to the fact that you use those manually configured ids... in our ASB we used a little more simple technique, this should solve this problem too, and many other..
The ASBContainer creates a unique ID based on a unique number formula, time + random of a large number + MD5, and that one becomes the ID, and it is passed to the AS2.0 source as a parameter (test.swf?asb_id=hg54fs7...), If the ASBTerminal gets an asb_id (a longer name actually) it will use it for the connection ID, otherwise, it will open the default communication port (named after the source, this was left only for protocol parameter sending failure) and it will negotiate a new ID from the ASBContainer, after this, the default communication port closes, and the connection is done via the negotiated ID.
I'm telling you all this in order to try implement this idea in your SWFBridge, which looks very cool to me, this way, you can load
A. the same AS2.0 swf inside an AS3.0 one at the same time but multiple times, and
B. load the same page on a single machine (that shares LocalConnection) for more than one time without getting conflicts.
Communication could also be done by using javascript (or other browser based open code), shared objects, server based communication (such as amfphp), there might be other ways to make these communicate, without problems, maybe some of you would like to try new methods.
We've created this ASB for simple reasons, such as: integrate an AS2.0 full functional ColorPicker component inside an AS3.0 project.
mario, if you think all flash devs are as good as you are in understanding the code that lies beyond the screen, you're not seeing the big picture. Most of our customers are flash designers and animatours, they like to have the most advanced things, made simple and easy for they to use them seamless.
Here is an article that we've opened so far about how we've thought about the ActionScript Bridge. In the future you might also find more useful information here. http://blog.jumpeyecomponents.com/
Posted by: raul at July 31, 2007 03:12 PMURL: http://www.jumpeyecomponents.com
LocalConnection-based is great and all, but what if I want to be able to use the return value? Is there any way to do synchronous communication between the swfs?
like:
// in AS3 -- i want to capture return value
var myname:String = myBridge.send("getName", userID);
// in AS2
function getName(userID) {
return nameList[userID];
}
///////////
Also one optimization might be to use Proxy in AS3 and __resolve in AS2 to make the typing simpler, ie:
Posted by: David R at July 31, 2007 04:58 PMmyBridge.myMethod("Hello", "World");
instead of:
myBridge.send("myMethod", "Hello", "World");
URL: http://blog.davr.org/
How funny, I ‘m working on a similar project that is going to be released on OS Flash called ASBridge.
I went the Local Connection route at first too but hit too many limitations:
* Local Connections not connecting in the debug player
* Asynchronous communication (ick)
* 40k (or so) data transfer limit
My project resolves all this and uses a AS2/3 delegate so a developer can interact between the objects directly while abstracting the implementation details.
I’ve been on the verge of release for a while but just haven’t had a chance to get it to a state where I want to distribute the source.
Posted by: erikbianchi at July 31, 2007 05:20 PMURL: http://www.erikbianchi.com
@David
in Jumpeye's ASB you can call from AS3 to AS2 either ASBContainer.run("_root.myScope.myFunction([myStringPa;rams])")
either
ASBContainer.run({scope:myScope,func:myFunc, [params..(any type)]})
and the second one can be done from AS2 to AS3, but without the scope, so it will run exactly on the ASBContainer's parent.
a ASBContainer.run method will retunr a task id, and the task id is used by the event listener method to release the return corectly.. like this:
var taskId = ASBContainer.run("myObject.myFunc(myStringParam)");
the RETURN event in AS3.0 will return objects like this {taskId:34,returnObject:myReturnObject}, so using a little more coding you can get back returns.
@erikbianchi
it's great that you guys are writing something similar to SWFBridge and to ActionScriptBridge, but I think you should change the name since it is similar to ours, and people will just get confused about it.
Posted by: raul at July 31, 2007 11:27 PMURL: http://www.jumpeyecomponents.com
Are you aware of Robert Taylor's work?
Posted by: jim bachalo at August 1, 2007 05:26 AMHe's had something similar available for almost a year now. Check it out...its amazing.
http://www.flashextensions.com/blog/2006/11/14/interfacing-between-flash-8-9-problems-and-solutions/
URL:
thanks jim, we didn't know about the flash interface before and we did some research on this; it seems that is a better approach than the SWFBridge, the guys at flashextensions are doing a great job anyhow, like gkinner ofcourse, we pretty much appreciate their work.
Posted by: raul at August 1, 2007 06:45 AMURL: http://www.jumpeyecomponents.com
There are, of course, advantages and disadvantages to using ExternalInterface, as there are for using LocalConnection.
Here's some info I posted a while ago:
Posted by: Derek Vadneau at August 8, 2007 02:01 PMhttp://tracethis.com/archives/2006/07/13/swf9-to-swf8-communication-ei-not-lc-part-1/
http://tracethis.com/archives/2006/07/13/swf9-to-swf8-communication-ei-not-lc-part-2/
URL: http://tracethis.com
Grant -- thanks for a great tool.
I, however, am having same problem as Edward mentioned above...it doesn't seem to work when trying to connect AS2.0 flash app with AS3.0 AIR app on OSX.
Did anybody else experience this?
- Daniel
Posted by: Daniel at August 9, 2007 08:30 PMURL: http://www.mcquilleninteractive.com
@raul
I agree. We will probably change the name to ASConnector or something along those lines.
In regards to Flash Extension I found a few issues that prompted me to write my own. In particular, it was impossible to get any kind of response or support via email or in their forums, documentation was light, out dated and gave conflicting examples that would not work and it makes use of some magic variables / functions on the root timeline.
My wife is 36 weeks pregnant so I doubt Ill get any progress on it anytime soon. =(
Posted by: erikbianchi at August 14, 2007 12:32 AMURL: http://www.erikbianchi.com
Thank you so much for this package. I'm using it for creating a local connection from AS3 to A2, as well as from AS3 to a loaded flex AS3.
Posted by: Michael at August 21, 2007 12:04 AMURL:
I'm getting some bug... when the as2 movie get the focus and then you try to set focus in the as3 movie… as2 movie don’t less the focus
Posted by: freddy at August 27, 2007 09:40 AMURL:
You sir, are a gentleman and a scholar, thank you!
Posted by: Michael Trim at September 19, 2007 07:41 AMURL:
Hello, and thank for all your great work. I am hoping to use this to connect, but I am getting an undefined method for out(p_evt);
Should this method be defined in your class? Thanks in advance!
-Z
Posted by: Zap at September 24, 2007 03:50 PMURL: http://N/A
Well, after seeing the debate between ASBridge and SWFBridge I thought I would try both of them out. For the actionscript rookies they might like the ASBridge component but there is much more flexibility and control using SWFBridge and the class method. I am comfortable in AS2 just started learning in AS3 and my choice is SWFBridge. Hope this helps someone!
Posted by: Steven King at September 30, 2007 09:46 PMSteven
URL:
You made my day 500x easier. THANK YOU!
Posted by: Scarybug at October 2, 2007 06:41 AMURL: http://scarybug.org
thanks! really helps!
Posted by: Jonathan Greene at October 3, 2007 01:41 PMURL: http://greenethumb.com
I'm using Flex Builder 3 and I cannot declare a variable of type SWFBridgeAS3. There are just two lines of code as shown below. Any ideas what i'm doing wrong?
code:
import com.gskinner.utils.SWFBridgeAS3;
error--> public var test:SWFBridgeAS3;
error: 1046: Type was not found or was not a compile-time constant: SWFBridgeAS3.
Posted by: olya at November 1, 2007 06:09 PMURL:
I thought I would give this a shot because I ran into an issue with my code, but the SWFBridge has the same issue.
For some reason the local connection dies when the function it calls runs too long.
PS: Why does the as3 version throw exceptions but the as2 version does not? shouldn't the as2 one throw the same exceptions?
Posted by: Jankrod at November 2, 2007 11:18 AMURL:
Wonderfully done, i get it work according to what i need in 15 mins
Posted by: vic~ at November 5, 2007 01:58 AMURL:
Hi, it's great, but it works only for as3 loading as2, not the other way round, doesn't it?
Posted by: weidler at December 6, 2007 11:26 AMURL:
@weidler
Posted by: Lanny at December 6, 2007 11:32 AMIt is not possible to load an AS3 swf into an AS2 shell.
URL: http://gskinner.com
Hi,
i m updating my e-learning course player project with Flash cs3 and AS3.0. the old version of course player was in As2.0. which load cousre swf files .
it was working fine Flash8 As2.0.
the player load course swf. the loaded course swf on a specifec frame call a method like this
_level0.setButton(2) method from course player;
The setButton(parameter) method defination is in new courser player. the loaded movie which is in Actionscritp2.0 not finding this method
in new course player which in Actionscript3.0. its working well with the old course player.
can any one give me solution to solve the issue.
i can't make changes in course swf files b/c there are thousand of course files
Posted by: shaneali at December 18, 2007 07:16 AMURL:
I was under the impression that running both the AVM1 and AVM2 within the same object/embed can hinder the performance of the app and is highly recommended to stay away from. Have I been misinformed or is this correct and you are just providing a solution but may not be the best for performance use? If this is correct and can hinder performance is the same true for running both AS2 and AS3 in multiple Object/Embed tags on a page? For instance many corporate pages that contain applications and many ads. The application may be AS3 running on the AVM1 and the ads AS2 running on the AVM1.
Thanks for your help,
Posted by: Tim O'Hare at December 20, 2007 07:53 AMTim O'Hare
URL: http://www.linkedin.com/in/timohare
If there is two AS3 APP run in client and load the same AS2 SWF ...
It will be... Oh my god...
Posted by: kita at December 21, 2007 07:40 AMURL:
Thanks a LOT Grant :-)
I needed to do exactly this for a job, and your class is so nifty and useful. Works soooo fine.
Have a nice day, and again: thanks :-)
Posted by: Daniele Giardini at January 25, 2008 07:23 PMURL: http://www.holoville.com
I tried the swfBridge and works ok locally. I imported AS2 (triggers an action to send to AS3) into AS3 (executes an action from AS2 trigger). Everthing is working locally but not when uploaded.
I tried capturing the variable passed by AS2 to AS3 and only woking locally.
Any ideas?
Posted by: frg10 at January 25, 2008 09:19 PMURL:
Its now working when uploaded but:
from AS3:
sb1.send("sbTest", "passToAS2");
works ok passing String but:
sb1.send("sbTest", passToAS2);
do not work passing variables.
ideas?
Posted by: frg10 at January 25, 2008 10:45 PMURL:
@Daniel
I am facing difficulties in calling AS 3 swf functions made in flex from AS 2 environment.
I am still debugging it.Can you help me out to solve this.
@All
I am using ASBridge but I got stuck while calling AS3 from AS 2.
It is throwin me error:
Error #2044: Unhandled AsyncErrorEvent:. text=Error #2095: flash.net.LocalConnection was unable to invoke callback getAndPass. error=ReferenceError: Error #1069: Property callAS3 not found on mx.core.UIComponent and there is no default value.
Posted by: Rajesh at February 8, 2008 12:23 PMcallAS3 is a function which I want to call from Flash 8(AS 2)
I am doing anything wrong here??
URL: http://flexworld.wordpress.com
sweet - great work grant!
i've used this to use the AS2 DateChooser in my AS3 project. It's a bit hefty at 35k just for a date picker, but it's worth it to have all the selectable/disabled date functionaility without spending days making my own and it only gets loaded if the user clicks to change the date.
i took a differenent approach to the multiple-connection issue raised by Andreas - I use 2 bridges, the first is only opened momentarily with a fixed id. When connected, the AS3 side generates a random id, opens the second bridge using it and sends it to the AS2 side to connect with it. Both sides close the first bridge, making it available to be used again.
Posted by: dave at March 10, 2008 03:19 PMURL:
it work great when the as2 application is simple, but...
Posted by: mali at March 19, 2008 08:30 AMi tried to use this on a project. i have a main as2 file that loads other as2 files. when the main as2 file is loaded to the as3 file, the other as2 files are not loaded properly. can this be solved?...
URL:
I just wanted to post this and make sure everyone else knows. I tried working with this class through the Document Class and the connection was never made. When I pulled out my code and placed it on the main timeline of my AS3 swf, the connection between the two documents was made.
Posted by: Todd at April 24, 2008 10:48 AMURL:
I began working with this bridge class and would love to continue using it. I'm having the uniqueID problem raul at jumpeye referred to because the AS2 swf is an activity module that is reloaded anytime the user returns to that (AS3)app 'node'. (So, bridge works great on 1st connect but fails on every subsequent send attempt - even though 'connect()' handlers are called, there is no actual connection). I tried using a random num derived dynamic id, passed in via the loaderObj's urlRequest like so: blah.swf?bridgeID=ran982675 , but the urlRequest obj throws a URL not found error when a query param is used that way. I can't pass in the var by adding it to the urlRequest, as in: urlReq.bridgeID=ran982675 because that is unrecognized by the loaded swf's AS2 code. Can anyone help with this? I'd really prefer not to have to back out and use some black-box component or a whole new class approach if possible.
Posted by: mcarey at April 28, 2008 12:03 PMThanks in advance for any insight...
URL:
In the meantime of sorting out the dynamic/random id issue, I've found a workaround. If interested, read on...
Posted by: mcarey at April 28, 2008 01:24 PMMy AS3 app handles 'node' nav. Since the onUnload event wasn't properly firing in the AS2 loaded activity in the context of an AS3 app that uses removeChild, I made the nodal nav responsible for cleanup of the connection if active (upon any call to displayNode(newNodeID)). In order for cleanup to occur properly on both ends, this check had to (1st): send a call to the AS2 loaded activity to kill its listener and close its connection, (2nd): kill the AS3 listener and close its connection [not entirely sure both ends need to do a close() but the redundancy doesn't hurt], (3rd): establish a timer (AS3 app) to check that the connection is fully closed (4th): return; (don't move on w/ new node display... lest the AS2 loaded content be 'removed' before the connection had a chance to close properly). This all seemed to work and allowed me to continue to use the same non-dynamic manual connection ID the next time that AS2 activity was (re)loaded.
Hope this helps anyone who runs across a similar issue!
URL:
For anyone trying to pass variables and has been unsucessfull, declare the variable as _global in AS 2.0 and AS 3.0 will pick it up.
Posted by: MM at May 31, 2008 05:30 AMURL:
Hi, how can i access the varuable in AS3 if i have defined global can you give an exmaple of declaring in AS2 and accessing it in as3
Posted by: Bilal at June 1, 2008 08:57 AMURL: http://actionscript-blog.imaginationdev.com
AS2 ->
import com.gskinner.utils.SWFBridgeAS2;
var sb1 = new SWFBridgeAS2("conn",this);
_global.param = "0x000000"
sb1.send("colorTransit",param);
AS3 ->
import com.gskinner.utils.SWFBridgeAS3;
var sb1:SWFBridgeAS3 = new SWFBridgeAS3("conn",this);
function colorTransit (param) {
Posted by: MM at June 6, 2008 01:09 PM//function code
}
URL:
I've been trying to open a connection using this bridge through one of my AS class files to no avail. If I create 2 instances of the class they open a bridge and talk to each other, but if I have 1 instance loading an AS2 swf (that has the AS2 bridge code on its main timeline) no connection gets established. Has anyone else run into problems like this?
Posted by: TGB at June 17, 2008 11:30 AMURL:
to Todd and TGB, if using a documentClass, try declaring the bridge instance in AS3 as a full member of the class.
private var sb1 : SWFBridgeAS3;
sb1 = new SWFBridgeAS3("test", this);
and not:
var sb1 : SWFBridgeAS3 = new SWFBridgeAS3("test", this);
worked for me...
Posted by: sitron at June 24, 2008 06:46 AMURL:
The bridge works well for me when I only load a single AS2 SWF into an AS3 parent SWF, and pass a variable from the parent to the child clip. However, once I load a second AS2 SWF (or more), the bridge doesn't want to pass the variable. I get this error:
"Error: A 'with' action failed because the specified object did not exist."
I have tried closing the connection and reopening a new connection, but that doesn't seem to work (or perhaps I'm not closing it correctly).
Has anyone had any luck opening several AS2 SWFs from within a parent AS3 SWF, and using the bridge to pass variables to each of the loaded child clips?
Posted by: CMS at July 4, 2008 02:23 PMURL:
Can it be the AS3 swfbridge does not handle multiple instances detections well? As a test I have opened the swf in a firefox window and compiled the same swf on CS3; as expected I got:
ArgumentError: Error #2082: Connect failed because the object is already connected.
at flash.net::LocalConnection/connect()
at com.gskinner.utils::SWFBridgeAS3()
Do I have to write a handler myself to clear this?
Posted by: grit at July 6, 2008 12:55 PMURL:
I changed the component by adding a error catch in lines 37 on. Now it handles in use connections:
myID = baseID+((host)?"_host":"_guest");
Posted by: grit at July 6, 2008 01:43 PMextID = baseID+((host)?"_guest":"_host");
if (!host) {
try {
lc.connect(myID);
} catch(e:ArgumentError) {
trace("SWFBridge ERROR: "+e);
}
lc.send(extID,"com_gskinner_utils_SWFBridge_init");
}
}
URL:
Local connection is not working when two swfs are in different domain???????????????. Pls suggest a working solution.....
Posted by: Linto at July 15, 2008 05:02 AMURL:
try to use allowDomain('*')
Posted by: graFF at July 28, 2008 05:20 AMURL: http://graffixtation.blogspot.com
Hi,
It seems the SWFBridgeAS3 does not seem to work with the FlashPlayer 10 Beta 2. I tried a very simple localconnection out of the box and that does work.
I must admit I haven't done extra tests. This was just a first try.
Maybe somebody has got the same problem?
Thanks!
Posted by: Wim Vanhenden at July 29, 2008 05:17 AMURL: http://seeing-is-believing.blogspot.com
Thanks for this info. It was very helpfull for me. However, I came to the conclusion that you can't have two applications using the same bridge open at the same time (try opening this page in two tabs).
I found a way to alert the users of this, but is there also a way to let the two bridges co-exist?
Posted by: Niels at August 1, 2008 04:47 AMURL: