Chapter 16. Client Data Communication

Flex applications are capable of many types of data communication, from the simple to the complex. Often when we think of data communication in Flex applications we think of client/server communications such as remote procedure calls (RPCs). However, some types of data communication occur entirely on the client side, and these types are the subject of this chapter.

At a minimum, all Flex applications require a client-side element in the form of a .swf file running in Flash Player. Some Flex applications even use several .swf files running in one or more instances of Flash Player on the client machine. The client-side portion of a Flex application is capable of several types of client data communication intended for a variety of purposes.

There are three main ways in which a Flex application can run data communications on the client:

Local connections

A local connection allows two .swf files to communicate as long as they are running on the same client machine at the same time. The .swf files can be running in two different instances of Flash Player. They can even be running in different host environments. For example, one .swf can be running in a web browser while another is running embedded within an executable running on the desktop. The .swf files can even communicate while served from different domains if configured correctly.

Shared objects

Local shared objects allow the application to store and retrieve persistent data on the client machine. For example, a user can save preferences that the application can retrieve automatically the next time the application runs.

External interface

The external interface is a mechanism by which a Flex application can communicate with the host environment. This allows the Flex application to run as an integrated part of a larger application. In practical terms, this means communicating with JavaScript in the containing HTML page.

The Flex framework does not provide special behaviors for working with client data communications. Rather, all of the topics in this book utilize low-level Flash Player API ActionScript.

Local Connections

Local connections are a way in which two .swf files can communicate even if they are running in two different Flash Player instances. Local connections allow you to create integrated applications composed of two or more .swf files running in separate Flash Player instances, such as several pods or modules that are part of a complex rich Internet application (RIA) that uses both Flex elements and HTML elements. Furthermore, local connections allow you to communicate between Flash 9 content (Flex applications) and older, legacy Flash content (Flash 8 or earlier).

Note

Local connections use Action Messaging Format (AMF), a binary messaging format, as the protocol for local connection data packets. A local connection request uses one AMF packet, and the maximum size for a local connection AMF packet is 40 KB. Local connections exclusively use a form of AMF called AMF0. This is in contrast with other ActionScript classes (such as flash.net.NetConnection), which can use AMF0 as well as AMF3, a newer form of AMF. AMF0 is compatible with older Flash content, making local connections a compatible way to communicate from Flex applications to older Flash content.

Basic Local Connection Communication

Typically when implementing local connections, at least two .swf files are needed: one that sends the requests and one that receives the requests. You cannot establish a local connection with a .swf without its explicit consent, because the receiving .swf must have the necessary code to listen for the specific requests.

Note

Technically it is possible to use a local connection to send and receive requests all within one .swf. However, in all practical cases, you will use two .swf files.

Both the sending and receiving .swf files use the flash.net.LocalConnection object. The LocalConnection object communicates over a named connection channel. The name of the channel is arbitrary and is a string value, but for the communication to work, the sending and receiving .swf files must send and receive over a channel with the same name.

The sending .swf uses the send() method of a LocalConnection object to send the request. The send() method requires at least two parameters specifying the name of the channel and the name of the method to call on the receiving .swf. The following example creates a new LocalConnection instance and calls the send() method:

var localConnection:LocalConnection = new LocalConnection();
localConnection.send("channel", "exampleMethod");

If the method in the receiving .swf expects parameters, you can pass them to the send() method following the name of the method to call. For instance, the following example calls exampleMethod on the receiving .swf and passes it integer parameters:

localConnection.send("channel", "exampleMethod", 10, 25);

The receiving .swf must listen for requests on the same channel as the sending .swf sends them. You can instruct a LocalConnection object to listen for requests by calling the connect() method, passing it the name of the channel to which to listen:

var receivingLocalConnection:LocalConnection = new LocalConnection();
receivingLocalConnection.connect("channel");

Warning

If you do not call the connect() method, the .swf will have no way of knowing that it should be listening for requests. In such a case, a sending .swf will throw errors if it cannot find the connection over which to send requests.

You must also tell the LocalConnection object where to direct the requests. For instance, when the sending .swf makes a request for exampleMethod, the receiving LocalConnection object needs to know where it can find exampleMethod. You can tell it where to find the method by assigning a reference to the appropriate object to the client property of the LocalConnection object. For example, the following tells the LocalConnection object on the receiver application where it can find the requested methods as methods of this class:

receivingLocalConnection.client = this;

Warning

The methods that you expose via a local connection must be declared as public. Otherwise, the application will throw an error. Methods must be defined for the object specified as the client of the receiving LocalConnection object.

This step of setting the client is essential. Without setting the client property, the LocalConnection object will throw errors when it receives requests.

Example 16-1 requires two MXML files compiled into two .swf files. The first MXML file creates the sending .swf. It contains a text area and a button. When the user clicks the button, the event handler sends a local connection request to call a method named displayMessage with a parameter equal to the value of the text area text.

Example 16-1. Local connection send example

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:Script>
        <![CDATA[

            import flash.net.LocalConnection;

            private var _localConnection:LocalConnection = new LocalConnection();

            private function sendMessage(event:MouseEvent):void {
                _localConnection.send("dataChannel", "displayMessage", message.text);
            }

        ]]>
    </mx:Script>

    <mx:VBox id="vbox">
        <mx:TextArea id="message" />
        <mx:Button label="Send" click="sendMessage(event)" />
    </mx:VBox>

</mx:Application>

Note

For the preceding example to clearly work, you must enter text into the text area before clicking the Send button.

The second MXML document defines the receiving .swf. This file (Example 16-2) contains a text area.

Example 16-2. Local connection receive example

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
initialize="initializeHandler(event)">

    <mx:Script>
        <![CDATA[

            import flash.net.LocalConnection;

            private var _localConnection:LocalConnection;

            private function initializeHandler(event:Event):void {
                _localConnection = new LocalConnection();
                _localConnection.connect("dataChannel");
                _localConnection.client = this;
            }

              // Note that this method is declared as public because it is
              // exposed as a method to a local connection.
            public function displayMessage(message:String):void {
                output.text += message + "
";
            }

        ]]>
    </mx:Script>

    <mx:TextArea id="output"  width="539" height="589"/>

</mx:Application>

The initializeHandler() method runs when the application initializes because it is set to handle the application initialize event, and it creates the LocalConnection object, connects to the channel to listen for requests, and designates this as the client for the requests, meaning that the requests get routed to methods of the same name defined for the MXML document. Notice that displayMessage() is declared as public. Methods called via a local connection must be declared as public.

Legacy Communication

One nonobvious use for local connections is to allow inter-.swf communication between Flash 9 (Flex) applications and content published to Flash 8 or earlier. Flex applications can load any sort of .swf, whether it was published from Flex or any version of Flash authoring. However, because Flash 9 applications use a fundamentally different virtual machine than older Flash content, it’s not possible for a Flash 9 application to communicate directly with a .swf published from Flash 8 or earlier. If a Flash 9 application loads a Flash 9 .swf, they can communicate directly by calling methods on the loaded .swf. However, that’s not possible when a Flash 9 application loads a Flash 8 or earlier .swf. That’s because Flash 9 and later content uses a completely separate ActionScript virtual machine (AVM) from that used by older content.

Local connection communication is a solution for interoperability, as it is supported by both older Flash content as well as Flash 9 applications. You can create a local connection API in the legacy content that the Flex application can call once it loads the .swf.

Cross-Domain Communication

In our discussion of local connection communication, we have thus far assumed that all communicating .swf files are in the same domain. By default, Flash Player disallows local connection communication when the .swf files are being loaded from different domains. However, you can explicitly allow cross-domain communication for a specific receiving .swf.

There are two basic types of cross-domain local connection communication: known domains communication and unknown domains communication. Known domains communication occurs when both the sending and receiving applications know about one another and the domains from which they are hosted. However, there are many cases in which the domains are not necessarily known at compile time. For example, you may use a local connection to create a plug-in-style application that can interact with many different applications. In such a case, you don’t necessarily know what all the possible domains are ahead of time.

The technique for unknown domains will work for both unknown and known domains, but it is also more lax. Therefore, it is recommended that you use the known domains technique whenever possible. If you must enable cross-domain communication but you do not know the domains from which the .swf files will be hosted, you can use the unknown domains technique.

To allow cross-domain local connection communication for known domains you must do two things: explicitly tell the receiving LocalConnection object to allow requests from the sending domain, and prefix the sending request channel name with the domain of the receiving .swf. Use the allowDomain() method to specify a list of all the domains to allow.

For the next example assume that the sending .swf is hosted at www.a.com and the receiving .swf is hosted at www.b.com. The following illustrates the code to send a request:

var localConnection:LocalConnection = new LocalConnection();
localConnection.send("www.b.com:channel", "exampleMethod");

The following illustrates the code necessary to receive the request with an application hosted at www.a.com:

var receivingLocalConnection:LocalConnection = new LocalConnection();
receivingLocalConnection.allowDomain("www.a.com");
receivingLocalConnection.connect("channel");
receivingLocalConnection.client = this;

When the domains are unknown, you can use the wildcard character (*) when calling allowDomain(), and rather than prefixing the channel with the receiving domain, you can name the channel with an initial underscore:

// Sending .swf
var localConnection:LocalConnection = new LocalConnection();
localConnection.send("_channel", "exampleMethod");

// Receiving .swf
var receivingLocalConnection:LocalConnection = new LocalConnection();
receivingLocalConnection.allowDomain("*");
receivingLocalConnection.connect("channel");
receivingLocalConnection.client = this;

Note

When testing cross-domain communication, it's useful to run the application using the debugger, which will notify you if there is a problem.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset