logo
Published on Highlander (http://www.highlander.co.uk)

Real Time Communication with Flex and AIR using ColdFusion and LiveCycle Data Services

By andy
Created 04/29/2008 - 23:46

In this walkthrough I’m going to take you through using ColdFusion (which contains LiveCycle Data Services) to create real time communication between an application in the browser and one on the desktop built with Adobe AIR. Both applications are written in Flex. You’ll see how we can create a better user experience on the desktop by using things like drag-and-drop and still tie that into a real time scenario inside of the browser.

The first thing you need to do is get ColdFusion 8 [1] or LiveCycle Data Services (LCDS) [2]. For this tutorial I’m using RTMP which BlazeDS [3] doesn’t support. I’ll have a BlazeDS example out later this week hopefully. ColdFusion has a LiveCycle Data Services install on top of it, so that’s what I’m going to use. You can grab all of the code from my SVN repository [4] under the GPXShare project [5]. You’ll also need my AS3 GPX library [6]. I’ve got a sample GPX file [7] you can use as well.

The second thing to be aware of is there are two general categories of communication in LiveCycle DS: the real time communication using RTMP [8] and data management. Data Management lets you do things like synchronize data between online and offline sources while real time communication allows you to push data to clients instead of having to force clients to check in with a server. Data management is included in LiveCycle DS but not Blaze DS and BlazeDS doesn’t support the RTMP protocol but does have support for AMF for psuedo-real time communication. For this I’m just talking about real time messaging over RTMP. Damon Cooper has a good blog post about the differences between RTMP and AMF [9] and how they apply to BlazeDS and LiveCycle DS.

The code is really, really simple. In my example, called GPXShare [10], I have two applications, one is a Flex-based application running in the browser [11] and the other is a Flex-based AIR application on the desktop [12]. You’ll see that I’m reusing a lot of code, one of the great things about using Flex is that you can quickly and easily move between the browser and the desktop. What I’m going to do is take an XML file with a bunch of GPS waypoints, drag it on to my AIR application, which will then send out that data to the browser application. You can have any number of browser applications open - each one “subscribes” to messages coming from the AIR application so they get the data in real time. The second part adds a tiny bit of collaboration. I want to be able to select a specific waypoint in either the AIR version or the Flex browser version and have that selection be highlighted on all the clients. All of that is really easy to do with LiveCycle Data Services.

Let’s first take a look at the AIR application [13]. In my AIR app I have two pieces of code which establish a Producer and Consumer:

. The Producer lets me send code out and the Consumer is what watches for changes. Each of those point to a destination which tells all of the connected clients how to pass the information back and forth. There are a couple of things we need to configure on the server now that we’ve seen the consumer and the producer.

 

So we’ve got our configuration files set up (you’ll have to rebuild your Flex project if you’re following along at home to make sure they get the new configuration settings). With that Producer/Consumer tag set up in our AIR application we’re ready to send out some data. Using the AIR API’s I’ve enabled drag and drop events from the file system so that when I drag in a GPX file, it will parse the data and display it in the grid. Once that happens we use the Producer to send the data out to all of our consumers with a doSend() function:

// Send our changes out to the consumers
public function doSend( array : Array ):void
{
// Create the message and set the message body to our data
var mess:AsyncMessage = new AsyncMessage();
mess.body.waypoints = array;
producer.send( mess );
}

The doSend() function is called after we finish opening the file from the file system and we just pass in the array of Waypoints. We create a new asynchronous message for storing our data and then set the body of that message to our data. In this case I’m sending an array with the name of waypoints. Finally we call the send() method on our Producer to fire it off. Now lets take a look at what happens inside of our browser application [15].

If you take a look at the code, you can see that we get to reuse a lot. Same data grid code and the same Producer/Consumer code. In this case, the browser is acting as a Consumer and you can see we’ve set the message attribute: message="doMessage( event );". This sets all of the consumers to watch for new messages and when they come in to call that doMessage function. So when we get message from our Consumer (the AIR application) with new GPS data, we call doMessage() in the browser:

// This is what happens when we get a message from the producer
public function doMessage( event:MessageEvent ):void
{
// Logic checks to see which kind of message we're getting
if( event.message.body.waypoints != null )
{
dg.dataProvider = event.message.body.waypoints as Array;
}
dg.selectedIndex = event.message.body.selectedIndex;
}

Pretty straight forward. We’re passing in a MessageEvent and that MessageEvent contains the waypoint array we passed in from the AIR application. The only semi-tricky thing is that because this application also sends the selected row information back and forth, I do a check to make sure we actually have waypoint data and not just a new selected row number.

So that’s it! The only other part to the application is sending the selected row back and forth. For that you can again reuse a lot of the same code between the AIR application and the browser application. In both applications we follow the same steps. Set up a change event to fire on our data grid when we select a new row which calls a doChangeSend() function. Then attach the selectedIndex to the message body and pass it through the AsyncMessage. Now when we receive that message we set the selectedIndex of our data grid:

// When we make a change to the datagrid we
// send a message with this function
public function doChangeSend( event : ListEvent ) : void
{
// Create the message and set the message body to our data
var mess:AsyncMessage = new AsyncMessage();
mess.body.selectedIndex = dg.selectedIndex;
producer.send( mess );
}
// When we get back a change event
// make sure the right index is selected
public function doMessage( event:MessageEvent ):void
{
dg.selectedIndex = event.message.body.selectedIndex;
}

That’s all there is to it. Remember you can grab the source code for both the browser-based Flex application and the desktop-based Flex application built with Adobe AIR [16] from my SVN repository. If you have any question, leave a comment or send me an email. Damon Cooper also has a great list of resources for BlazeDS and LiveCycle Data Services [17] for more information.



Source URL:
http://www.highlander.co.uk/real-time-communication-flex-and-air-using-coldfusion-and-livecycle-data-services