Building data-intensive RIAs – part 1

As part of the recent European onAIR tour I presented a session on building data-intensive AIR applications – the aim of this follow-up series of three blog posts is to highlight some of the options available for incorporating data in your Flex applications, either in the browser or when running as a desktop-based application.

What is a data-intensive RIA?

There will no doubt be differing views on the exact definition of a data-intensive RIA; if however, we consider the scenarios where basic data exchange using XML over HTTP or SOAP-based web-services fail to provide the performance or functionality required to deliver a rich, engaging online experience, then these are likely to be good candidates for applications that can be described as data intensive.

So, what are the scenarios where basic data exchange doesn’t always meet our requirements? Well, what if we need to consume large amounts of data in our application; maybe thousands or tens of thousands of records need to be available on the client-side and it’s taking a long time to retrieve, parse and display the data? Or, what if our data is changing rapidly and the client-side application always needs to display the most up-to-date information? And finally, what if we need to ensure that information entered into our application is always in-sync with the server, including scenarios where the end-user is making changes to data when offline.

Over the course of these posts I’ll explore each of these scenarios, introduce BlazeDS and LiveCycle Data Services and explain how they can be used to overcome the limitations of using basic HTTP and SOAP data exchange for data-intensive applications. If you want to view or download the slides from my onAIR tour presentation, these are posted below:

[kml_flashembed movie=”https://share.acrobat.com/adc/flex/mpt.swf” height=”400″ width=”450″ fvars=”ext=ppt&docId=e5b54f1c-c51d-49a2-88ee-7239b8503ab7″ /]

Introducing BlazeDS and other comparable technologies

BlazeDS provides server-based Java remoting and web messaging technology, is free and open source, and can be highly scaled by moving your application to LiveCycle Data Services (LCDS) at a later point in time. If you’re using ColdFusion then you can use the LCDS server that comes installed with ColdFusion, or swap it out for BlazeDS (although for this post, you don’t need BlazeDS or LCDS as you use remoting straight out of the box with ColdFusion CFCs). If you’re using .NET, PHP or Ruby as your back-end then you might want to take a look at WEBOrb, which provides an alternative implementation of the remoting and web messaging technology in BlazeDS.

Installing BlazeDS

Assuming that you want to follow along and use BlazeDS, you’ll need to download and install it by following these steps:

1. Grab the BlazeDS turnkey install at http://opensource.adobe.com/wiki/display/blazeds/Release+Builds
2. Unzip it somewhere convenient (referred to as {install} below)
3a. On Mac OS X: start the server from the Terminal by moving to the {install}/tomcat/bin/ directory and typing ./startup.sh
3b. On Windows: start the server from the Command Line by moving to the {install}/tomcat/bin/ directory and typing startup.bat
4. Test that your BlazeDS install has worked by going to http://localhost:8400/samples/ in your preferred browser
5. Start the sample database that comes with BlazeDS by moving to the {install}/tomcat/sampledb/ and typing ./startdb.sh on Mac OS X or startdb.bat on Windows.

If something went wrong then please check the release notes and installation guide.

Using Remoting Services for data exchange

Let’s start in this post by looking at using BlazeDS to transfer data from the server to our Flex application. The amount of time it takes to generate, transfer, parse and render the data becomes increasingly important as the amount of data we consume in our application increases; the efficiency of the data transfer from a bandwidth perspective can also become a concern.

To demonstrate these issues, fellow evangelist James Ward created an application which provides benchmarks for loading data into Rich Internet Applications. Try using his ‘Census‘ tool to load 10,000 rows of data into Flex, firstly using XML (E4X) and then using AMF (the binary data format used within BlazeDS) – you should see a marked reduction in the time taken to retrieve/display data and the bandwidth consumed when using AMF.

Assuming that you’ve been using the HTTPService or WebService tags within your Flex application, you’ll need to make some changes to your application to make use of BlazeDS remoting and the AMF data format. With the RemoteObject tag in Flex, and BlazeDS installed on the server, you can directly invoke methods of Java objects deployed in your application server and consume the return value – which could be a primitive data type, an object, a collection of objects or an object graph.

Taking the Remoting example included within the BlazeDS Test Drive (at http://localhost:8400/samples/testdrive.htm if you installed BlazeDS as per the instructions above), we can see the following client-side code is used to invoke the getProducts method, the result of which is bound to a DataGrid component:


	
	
	

You’ll notice that unlike the WebService and HTTPService tags, we’re not defining the WSDL or URL directly in the application, instead we’re referencing a destination called ‘product’.

Using Destinations

BlazeDS and LiveCycle Data Services use a number of configuration files on the server to define destinations – as we’ll see over the course of these posts, destinations are used with remote object invocation, messaging and (in LiveCycle) the data management service. The configuration file that defines the destinations for use with our RemoteObject tag is at {install}/tomcat/webapps/samples/WEB-INF/flex/remoting-config.xml and contains the following definition for the ‘product’ destination:


    
          flex.samples.product.ProductService
    

The destination is mapped to a fully qualified Java class on our application server – by taking this approach, and not defining the physical location of the data in our Flex application, we enable centralized management of data services, improve the security of our application (if your application is decompiled no information about the physical location of data services can be obtained) and increase deployment flexibility (by having the option to change the server-side implementation without updating the physical location within the Flex application).

Typed ActionScript Objects

When receiving data, Java objects are deserialized into either dynamic or typed ActionScript objects depending upon whether you have mapped the appropriate ActionScript class to the Java equivalent. To create typed ActionScript objects you must use a compiler directive within your ActionScript class to define the location of the corresponding Java class, in the format [RemoteClass(alias=”packageName.ClassName”)].

For a working application which uses this technique examine the “Updating data” sample from the BlazeDS Test Drive (again, at http://localhost:8400/samples/testdrive.htm if you installed BlazeDS as per the instructions above). An example of an ActionScript class mapped to a remote Java class is shown below:

package
{
	[Bindable]
	[RemoteClass(alias="flex.samples.product.Product")]
	public class Product
	{
		public function Product()
		{
		}

		public var productId:int;
		public var name:String;
		public var description:String;
		public var image:String;
		public var category:String;
		public var price:Number;
		public var qtyInStock:int;
	}
}

Channels

BlazeDS and LCDS separate out the transfer formats and network protocols used to send/receive data over the network from the destination definition – these are defined as channels within the services-config.xml configuration file on the server. In the case of remote object invocation we are using the default AMF over HTTP channel, but there is also an AMF over HTTPS channel that you could choose to use. If you take a look at the services-config.xml file you’ll notice that the endpoint location is defined as:

	

where server.name, server.port and context.root are all defined dynamically. For browser-based applications these values will be defined at runtime, based on where the SWF file is deployed. For AIR applications, this represents a challenge however, as the endpoint can’t be resolved at runtime from the end user’s desktop; instead, we must programmatically set the endpoint used by the channel, as shown in the example below:


	
	
	

An alternative approach is to use the mx.messaging.ChannelSet class to define endpoints; we’ll use this when we look at using messaging and the data management service with AIR applications in a future post.

Summary

That covers the basics for using BlazeDS and AMF to improve the efficiency of consuming data within your Flex application – if you have applications that retrieve large volumes of data then I’d certainly encourage you to try out BlazeDS. More information on this topic can be found on the Adobe Developer Centre and in the Blaze Developer Guide.

Next time I’ll take a look at how we can use the BlazeDS messaging service to ensure our application can display real-time changes to data, as well as to enable collaborative application functionality.

Advertisements
This entry was posted in AIR, Flex, Rich Internet Apps. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s