Search

 

May 2009
S M T W T F S
« Apr   Jun »
 12
3456789
10111213141516
17181920212223
24252627282930
31  

Tags

Archives


« | Main | »

LocalConnection – Maintaing connection between AIR applications

By Rich Tretola | May 27, 2009
7,666 views

In my 360Flex presentation last week in Indianapolis I used LocalConnection to communicate between two AIR applications. Here is a very simple sample of how I set up the two applications to talk to each other.

So, the general concept is this. I have 2 AIR applications, one is the Primary and the other is the Slave. They will communicate with each other over LocalConnection and also utilize a polling methodology as a method of notification when one of the applications is not available.

Primary

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
                        creationComplete="init()">
    <mx:Script>
        <![CDATA[
            // primaryLC is this application
            public var primaryLC:LocalConnection = new LocalConnection();
            // slaveLC is the remote app
            public var slaveLC:LocalConnection = new LocalConnection();

            /**
             * connection string to talk to an AIR application is made up of
             * app# + application id + . + publisher id + : + application id
             * example: app#Slave.130A080AFCC69239D6F9896EEBED2327BC93ED43.1:Slave
             * to use this sample, you must fill in your appropriate connection string below
            */

            private static const slaveLCConection:String = ""

            // timer to ping LocalConnection
            private var lcTimer:Timer;

            [Bindable]
            private var connected:Boolean = false;

            [Bindable]
            [Embed ('thumbsdown.png')]
            private var thumbsdown:Class;

            [Bindable]
            [Embed ('thumbsup.png')]
            private var thumbsup:Class;

            private function init():void{
                // create LocalConnection
                primaryLC.allowDomain('*');
                primaryLC.client = this;
                primaryLC.connect("Primary");
                slaveLC.addEventListener(StatusEvent.STATUS, lcStatusChanged);

                // start a timer to ping the Slave
                lcTimer = new Timer(1000, 0);
                lcTimer.addEventListener(TimerEvent.TIMER, timerHandler);
                lcTimer.start();
            }

            // ping the Slave
            public function timerHandler(event:TimerEvent):void {              
                slaveLC.send(slaveLCConection, "testCon", primaryLC.domain + ':Primary');
            }

            // receive LocalConnection response
            public function testCon():void{
                connected = true;
            }

            // handle status changes
            private function lcStatusChanged(event:StatusEvent):void{
                if(event.level == "error")connected = false;
            }
        ]]>
    </mx:Script>

    <mx:Image source="{(connected)?thumbsup:thumbsdown}"
              horizontalCenter="0" verticalCenter="0"/>

</mx:WindowedApplication>

Slave

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
                        creationComplete="init()">
    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            // primaryLC is the remote app
            public var primaryLC:LocalConnection = new LocalConnection();
            // slaveLC is this app
            public var slaveLC:LocalConnection = new LocalConnection();

            // timer to ping LocalConnection
            private var lcTimer:Timer;

            private var responseConnectionName:String;

            [Bindable]
            private var connected:Boolean = false;

            [Bindable]
            [Embed ('thumbsdown.png')]
            private var thumbsdown:Class;

            [Bindable]
            [Embed ('thumbsup.png')]
            private var thumbsup:Class;

            private function init():void{
                // create LocalConnection
                slaveLC.allowDomain('*');
                slaveLC.client = this;
                slaveLC.connect("Slave");
                //mx.controls.Alert.show("My pubId is \n" + slaveLC.domain);
                primaryLC.addEventListener(StatusEvent.STATUS, lcStatusChanged);
            }

            // handle status changes
            private function lcStatusChanged(event:StatusEvent):void {
                if(event.level == "error")connected = false;
            }

            // receive LocalConnection response
            public function testCon(responseConnectionName:String):void{
                connected = true;
                this.responseConnectionName = responseConnectionName;
                if(lcTimer == null){
                    // start a timer to ping the Primary
                    lcTimer = new Timer(1000, 0);
                    lcTimer.addEventListener(TimerEvent.TIMER, timerHandler);
                    lcTimer.start();
                }
            }

            // ping the Primary
            public function timerHandler(event:TimerEvent):void {              
                primaryLC.send(responseConnectionName, "testCon");
            }
        ]]>
    </mx:Script>

    <mx:Image source="{(connected)?thumbsup:thumbsdown}"
              horizontalCenter="0" verticalCenter="0"/>

</mx:WindowedApplication>

OK, so what is actually going on in the sample code above?

Lets first take a look at the Primary application source code. Here are the key points:

Upon init() of the Primary application, the primaryLC LocalConnection object is instantiated and an eventListener is setup to listen for status changes to the slaveLC LocalConnection object. A timer lcTimer is also instantiated and scheduled to run every 1 second in which time it will call the testCon method on the Slave. You can see this outbound call in the timerHandler method. Notice that I am passing along the Primary‘s domain so that the Slave can call back to the Primary without having to have the Primary‘s connection string hard coded.

Upon init() of the Slave application, the slaveLC LocalConnection object is instantiated and an eventListener is setup to listen for status changes to the primaryLC LocalConnection object. A timer lcTimer is also instantiated and scheduled to run every 1 second in which time it will call the testCon method on the Primary. You can see this outbound call in the timerHandler method.

So, here is the possible chain of events.

If Primary is launched first, it begins polling for a connection to Slave by calling the Slave‘s tectCon method every 1 second. If and when Slave is found and the call to testCon succeeds, Slave will set its connected property to true and set the responseConnectionString to what was passed in from Primary. Finally, it will begin polling Primary as well. Once Primary‘s testCon method is called from Slave, it sets its connected property to true as well.

If Slave is launched first, it will simply sit and wait as it doesn’t begin polling Primary until Primary makes the first call to Slave‘s testCon method which sets the Primary‘s responseConnectionName and starts the Slave‘s polling timer.

This system works very well to ensure that both applications have awareness about the connection status to each other and also only requires that you hard code one of the connection strings.

If you have other ideas, please feel free to share. I hope this tutorial helps.

If you are having trouble finding the connection string to plug in to line 17 of the Primary, you can uncomment line 33 of Slave and install on your local system. The Alert that pop up on launch will be the string that should be entered on line 17 of Primary.

Note: this can also be used within 2 browser based Flash Player or an AIR application talking to a browser based Flash Player application, although some changes to the connection string would be required if the Slave was in the browser.

Topics: 360Flex, Adobe AIR, Flex | 15 Comments »

15 Responses to “LocalConnection – Maintaing connection between AIR applications”

  1. Peter Wong Says:
    May 27th, 2009 at 12:22 pm

    Hey Rich,
    I can see a good chunk of the use cases for doing something like this is to offload processing to another thread or process.

    Have you heard any plans on Adobe’s side to make this easier to do right of the box and packages well?

    I mean, like have 2 modules connect through LocalConnection and have them run on separate threads/processes?

    I’ve been watching ASC-3222 (http://bugs.adobe.com/jira/browse/ASC-3222) and it doesn’t seem to be going anywhere despite the demand…

    Reply to this comment

    Rich Tretola Reply:

    That was actually the concept of my presentation. Unfortunately, it appears that even though the AIR processes run separately, they ultimately share a single Flash Player and a spike on any process will freeze the entire runtime.

    Reply to this comment

    Evan Reply:

    Hey Rich,
    I’m not following what you mean by “they ultimately share a single Flash Player”… do you have a reference you could link to that might explain this in more detail?

    Reply to this comment

    Rich Tretola Reply:

    The AIR runtime utilizes the flash player just as content running in the browser. Even though you may have multiple AIR applications running on your OS, they are sharing a single flash player.

    Akhilesh Reply:

    Hi Rich,
    Nice to see the communication between two AIR application.My question is, Can one AIR application communicate with another RIA application? Can u plz explain regarding this.
    Thanks

    Rich Tretola Reply:

    Yes, AIR can talk to Flash Player in the browser. See these examples:

    http://blog.everythingflex.com/2008/01/11/more-fun-with-air-localconnection-source-included/

    http://blog.everythingflex.com/2008/01/02/happy-new-year-localconnection/

    Basically, as long as the flash player is involved and you own both applications they can both be AIR, both be Flash in the browser or be one of each.

  2. Twitted by jinixx Says:
    May 28th, 2009 at 10:14 am

    [...] This post was Twitted by jinixx – Real-url.org [...]

  3. Serhiy Says:
    September 11th, 2009 at 9:45 am

    Hi,

    I am working with the same issue – in the project purpose it is required to establish communication between two air application. I tried you example and it doesn’t work on my PC.

    -Regards,
    Serhiy Vasilyev

    Reply to this comment

  4. Patrick Says:
    February 12th, 2010 at 1:07 pm

    This example fails to work, do you know this?

    Reply to this comment

    Rich Tretola Reply:

    Did you set the slaveLCConection correctly? What error are you seeing?

    Reply to this comment

    Rich Tretola Reply:

    Also, what version of AIR are you using? This won’t work with AIR 2.

    Reply to this comment

  5. Rich Tretola Says:
    February 12th, 2010 at 6:45 pm

    Did you see my other questions above?

    Reply to this comment

  6. sebastian Says:
    March 12th, 2010 at 12:41 am

    Hello,

    i have a some problems by using LocalConnections. The Target is a bi-directional communication between Flex and Air (use SDK 4 (AIR 1.5.3)).

    The Setup: Flex-Application is located in Domain http://www.xyz.de, the AIR-App. is local installed.

    My Setup works very well in Domains like “xyz.de”, but when i change to something like this: “www.some-domain-include.de” i got no communication from AIR to flex (flex to Air is ok).
    The “-” in my url-name seems to be a problem, is that right?

    The sample-Files (with source-code) are online at:
    http://homepages.uni-paderborn.de/spider/LocalConnectionTestAir.air
    and
    http://homepages.uni-paderborn.de/spider/LocalConnectionTestFlex.swf

    You can try it. Press the button “ping” in Flex-App. If ping works fine you get a MSG-Box in AIR. Now press Answer, the Flex-App get a Result or not :( (The same unmodified Code, is running on Domains like xyz.de)

    Thanks
    Sebastian

    Reply to this comment

  7. Grill restaurant - Mountain restaurant - Fire grill mountain restaurant Says:
    August 23rd, 2010 at 7:27 pm

    [...] LocalConnection – Maintaing connection between AIR applications 27 May 2009. evden eve nakliyat on Flash on my TV? all star shoes on.. single Flash Player and a spike on any process will freeze the entire runtime..blog.everythingflex.com/…/localconnection-maintaining-connections/ – LocalConnection – Maintaing connection between AIR applications [...]

  8. Dress up hot girl game - Dress game - Dress up games for girls Says:
    September 14th, 2010 at 4:07 am

    [...] LocalConnection – Maintaing connection between AIR applications 27 May 2009. evden eve nakliyat on Flash on my TV? all star shoes on.. single Flash Player and a spike on any process will freeze the entire runtime..blog.everythingflex.com/…/localconnection-maintaining-connections/ – LocalConnection – Maintaing connection between AIR applications [...]

Comments