Category Archives: Flex

Multi-Device Best Practices

I recently spoke at the 360|Flex conference in Devner, CO on “Multi-Device Best Practices”.  This presentation was focused upon multi-device & multi-platform development strategies for both PhoneGap and Flex/AIR applications.  Below you can view my presentation slides and source code, and a brief summary.

First, I gave an overview of mobile & multi-platform with AIR and PhoneGap.  See these links for more detail on the platforms:

Next, I emphasized the differences in user experience, display density, usability, and application style/feel between different platforms and device form factors.  You can read more detail on these topics here:

I also covered various libraries and techniques for making your creations feel like “native apps” instead of “web pages in a container”, and ways to make your apps look & feel “more native” for a given platform.

Details on Flex/AIR-specific tools & frameworks for native-like app experiences:

Frameworks/Libraries for HTML/Web/PhoneGap, for “app-like” experiences:

Feel free to leave a comment with any questions.
Enjoy!

Adobe’s View of Flex & Future Commitment

Adobe has just published a white paper detailing current views and future commitments to Apache Flex. Included topics are contributions to Apache, commitments to the Flash platform, and commitments to Adobe customers.   I strongly recommend that all Flex developers and project stakeholders read this:

Or, download and read the pdf version.

Here’s an excerpt:

Summary

Adobe believes that Flex is the best solution for enterprise and data-centric application development today and is moving Flex into a community-driven open source project to ensure the continued development and success of Flex for years to come. We are currently in the process of contributing the core Flex SDK, automation libraries, AIR SDK binaries, and documentation to the Apache Flex Project. We will also be contributing Falcon, Falcon JS, Mustella, and BlazeDS.

In addition to these contributions, Adobe is providing a team of full-time Flex SDK engineers who will contribute to and support the Apache Flex Project. These Adobe engineers will work directly with the highly skilled Flex developer community to maintain, support, and evolve the Flex SDK. We remain committed to enabling the success of all existing and new Flex projects.

Stage3D & Flex Demo w/ Source

Back in the summer, I was lucky enough to get my hands on some early builds of Stage3D for mobile. I built some simple examples, including basic geometric shapes and simple 3D bubble charts inside of mobile Flex/AIR applications. I have been asked numerous times for the source code, and I’ve finally given in, and am sharing some source code.

I am not posting the full mobile application source code, since Stage3D for mobile is not yet available. However, I have ported the 3D bubble chart example to run in a Flex application targeting the desktop (Flash Player 11). The bubble chart example extends the concepts explored in the basic geometric shapes example.

Before you say “shoot, he didn’t give us the mobile code”, let me explain… When I ported the code from the mobile project to the desktop Flex project, all I changed was code specific to the mobile Flex framework. I changed <s:ViewNavigatorapplication> to <s:Application> and the corresponding architecture changes that were required, and I changed the list item renderers to Spark item renderers based on <s:Group> instead of mobile item renderers.   In the mobile item renderers, all my drawing logic was done using the ActionScript drawing API.  For simplicity in the port, I just used <s:Rect> to add the colored regions in the desktop variant.

That is all I changed!  

The stage3D code between the desktop and mobile implementations is identical.    You can see the desktop port in action in the video below:

Or, you can test it for yourself here:

The source code was intended to be exploratory at best… I was simply experimenting with hardware accelerated content, and how it can be used within your applications.   There is one big “gotcha” that you will have to watch out for if you want Stage3D content within a Flex application… Stage3D content shows up behind Flex content on the display list.   By default, Flex apps have a background color, and they will hide the Stage3D content.   If you want to display any Stage3D content within a Flex application (regardless of web, desktop AIR, or mobile), you must set the background alpha of the Flex application to zero (0).  Otherwise you will pull out some hair trying to figure out why it doesn’t show up.

The source code for the web/Flex port of this example is available at:

This also requires inclusion of the Away3D library, available at:

You can check out my original posts, showing Stage3D on mobile here:

You can also check out a video of this code running on a mobile device (Samsung Galaxy Tab 10.1) below:

Enjoy!

2012 Flex User Group Tour: North America Dates Announced

If you hadn’t heard already, Flex has been accepted by the Apache Software Foundation. If you are wondering what exactly this means, or you have asked yourself any of the following questions, then you might want to check out the Adobe Flex User Group Tour:

  • Do you want to learn more about the future of Flex?
  • Do you want to learn more about the Flex transition to the Apache Software Foundation?
  • How can you contribute and help make Flex thrive?
  • Do you have questions that you would like to voice to Adobe?

As promised, Adobe is kicking off The Flex User Group Tour to discuss recent events surrounding Flex and the Flash Platform.   These meetings are intended to help you understand the changes happening with Flex and Flash, the impact to related tools, as well as to educate about the process & transition to Apache.   You can learn more about the user group tour and get an up-to-date listing of dates & cities from the Flex Team blog - be sure to check back periodically for updates. Initial cities include New York, Boston, Denver, Seattle, Los Angeles, Sand Diego, and Dallas.   Expect more cities & countries to be announced at a later date.

We hope to see you at one of the upcoming events. I’m scheduled to speak at the Dallas event in April, and I hop to see you there!

Realtime Data & Your Applications

After spending some time playing around sketching with the HTML5 canvas element earlier this week, I figured “why not add some ‘enterprise’ concepts to this example?”…  Next thing you know we’ve got a multi-device shared sketching/collaboration experience.

To keep things straightforward, I chose to demonstrate the near-realtime collaboration using a short-interval HTTP poll.  HTTP polling is probably the simplest form of near-realtime data in web applications, however you may experience lag when compared to a socket connection of equivalent functionality.   I’ll discuss the various realtime data options you have in Flex/Flash and HTML/JS and their pros & cons further in this post.

What you’ll see in the video below is the sketching example with realtime collaboration added using short-interval data polling of a ColdFusion application server.  The realtime collaboration is shown between an iPad 2, a Kindle Fire, and a Macbook Pro.

Before we get into the code for this example, let’s first review some realtime data basics…

First, why/when would you need realtime data in your applications?  Here are just a few:

  • Time sensitive information, where any delay could have major repercussions
    • Realtime financial information
    • Emergency services (medical, fire, police)
    • Military/Intelligence scenarios
    • Business critical efficiency/performance metrics
  • Collaboration
    • Realtime audio/video collaboration
    • Shared experience (presentations/screen sharing)
  • Entertainment
    • Streaming media (audio/video)
    • Gaming

Regardless of whether you are building applications for mobile, the web, or desktop, using any technology (Flex/Flash, HTML/JS, Java, .NET, Objective C, or C/C++ (among others)), there are basically 3 methods for streaming/realtime data:

  • Socket Connection
  • HTTP Polling
  • HTTP Push

Socket Connections

Socket connectionss are basically end-to-end communications channels between two computer processes.   Your computer (a client) connects to a server socket and establishes a persistent connection that is used to pass data between the client and server in near-realtime.   Persistent socket connections are generally based upon TCP or UDP and enable asynchronus bidirectional communication.   Binary or Text-based messages can be sent in either direction at any point in time, in any sequence, as data is available.   In HTML/JS applications you can use web sockets, which I recently discussed, or use a plugin that handles realtime socket communication. Did you also know that the next version of ColdFusion will even have web socket support built in?  In Flash/Flex/AIR, this can be achieved using the RTMP protocol (LCDS, Flash Media Server, etc…) or raw sockets (TCP or UDP).

Direct Socket Communications

In general, direct socket based communication is the most efficient means of data transfer for realtime application scenarios.  There is less back and forth handshaking and less packet encapsulation required by various protocols (HTTP, etc…), and you are restricted by fewer network protocol rules.  However, socket based communications often run on non-standard or restricted ports, so they are more likely to be blocked by IT departments or stopped by network firewalls.    If you are using socket based communication within your applications, which are running on non-standard ports, and you don’t govern the network, you may want a fallback to another realtime data implementation for failover cases.

HTTP Polling

HTTP Polling is the process of using standard HTTP requests to periodically check for data updates on the server.  The client application requests information from the server.  Generally, the client will send a timestamp indicating the last data update time.  If there is information available on the server that is newer than the timestamp, that data will be immediately sent back to the client (and the client’s timestamp will be updated).   After a period of time, another request will be made, and so forth until the polling is stopped within the application.  Using this approach, the application is more-or-less “phoning home” periodically to the server to see if there are any updates.  You can achieve near-realtime performance by setting a very short polling interval (less than one second).

Basic Data Poll Sequence

HTTP polling uses standard web protocols and ports, and generally will not be blocked by firewalls.  You can poll on top of standard HTTP (port 80) or HTTPS (port 443) without any issue.  This can be achieved by polling JSON services, XML Services, AMF, or any other data format on top of a HTTP request.   HTTP polling will generally be slower than a direct socket method, and will also utilize more network bandwidth b/c of request/response encapsulation and the periodic requests to the server.  It is also important to keep in mind that the HTTP spec only allows for 2 concurrent connections to a server at any point in time.  Polling requests can consume HTTP connections, thus slowing load time for other portions of your application.   HTTP polling can be employed in HTML/JS, Flex/Flash/AIR, desktop, server, or basically any other type of application using common libraries & APIs.

HTTP Push

HTTP Push technologies fall into 2 general categories depending upon the server-side technology/implementation.  This can refer to HTTP Streaming, where a connection is opened between the client and server and kept open using keep-alives.   As data is ready to send to the client, it will be pushed across the existing open HTTP connection.   HTTP Push can also refer to HTTP Long Polling, where the client will periodically make a HTTP request to the server, and the server will “hold” the connection open until data is available to send to the client (or a timeout occurs).   Once that request has a complete response, another request is made to open another connection to wait for more data.  Once Again, with HTTP Long Poll there should be a very short polling interval to maintain near-realtime performance, however you can expect some lag.

HTTP Long Poll Sequence

HTTP Streaming & HTTP Long polling can be employed in HTML/JS applications using the Comet approach (supported by numerous backend server technologies) and can be employed in Flex/Flash/AIR using BlazeDS or LCDS.

Collaborative Applications

Now back to the collaborative sketching application shown in the video above… the application builds off of the sketching example from previous blog posts.   I added logic to monitor the input sketches and built a HTTP poll-based monitoring service to share content between sessions that share a common ID.

Realtime Collaborative Sketches

In the JavaScript code, I created an ApplicationController class that acts as an observer to the input from the Sketcher class.   The ApplicationController encapsulates all logic handling data polling and information sharing between sessions.   When the application loads, it sets up the polling sequence.

The polling sequence is setup so that a new request will be made to the server 250MS after receiving a response from the previous request.  Note: this is very different from using a 250MS interval using setInterval.  This approach guarantees 250MS from response to the next request.  If you use a 250MS interval using setInterval, then you are only waiting 250MS between each request, without waiting for a response.  If your request takes more than 250 MS, you will can end up have stacked, or “concurrent” requests, which can cause serious performance issues.

When observing the sketch input, the start and end positions and color for each line segment get pushed into a queue of captured transactions that will be pushed to the server.  (The code supports multiple colors, even though there is no method to support changing colors in the UI.)

ApplicationController.prototype.observe = function(start, end, color) {
	this.capturedTransactions.push( {"sx":start.x, "sy":start.y, "ex":end.x, "ey":end.y, "c":color} );
}

When a poll happens, the captured transactions are sent to the server (a ColdFusion CFC exposed in JSON format) as a HTTP post.

ApplicationController.prototype.poll = function () {
	this.pendingTransactions = this.capturedTransactions;
	this.capturedTransactions = [];

	var data = { "method":"synchronize",
				 "id":this.id,
				 "timestamp":this.lastTimeStamp,
				 "transactions": JSON.stringify(this.pendingTransactions),
				 "returnformat":"json" };

	var url = "services/DataPollGateway.cfc";
	$.ajax({
	  type: 'POST',
	  url: url,
	  data:data,
	  success: this.getRequestSuccessFunction(),
	  error: this.getRequestErrorFunction()
	});
}

The server then stores the pending transactions in memory (I am not persisting these, they are in-ram on the server only).   The server checks the transactions that are already in memory against the last timestamp from the client, and it will return all transactions that have taken place since that timestamp.

<cffunction name="synchronize" access="public" returntype="struct">
    <cfargument name="id" type="string" required="yes">
    <cfargument name="timestamp" type="string" required="yes">
    <cfargument name="transactions" type="string" required="yes">

    <cfscript>

        var newTransactions = deserializeJSON(transactions);

        if( ! structkeyexists(this, "id#id#") ){
            this[ "id#id#" ] = ArrayNew(1);
        }

        var existingTransactions = this[ "id#id#" ];
        var serializeTransactions = ArrayNew(1);
        var numberTimestamp = LSParseNumber( timestamp );

		//check existing tranactions to return to client
        for (i = 1; i lte ArrayLen(existingTransactions); i++) {
            var item = existingTransactions[i];
            if ( item.timestamp GT numberTimestamp ) {
                ArrayAppend( serializeTransactions, item.content );
            }
        }

        var newTimestamp = GetTickCount();

		//add new transactions to server
        for (i = 1; i lte ArrayLen(newTransactions); i++) {
            var item = {};

            if ( structkeyexists( newTransactions[i], "clear" )) {
                serializeTransactions = ArrayNew(1);
                existingTransactions = ArrayNew(1);
            }

            item.timestamp = newTimestamp;
            item.content = newTransactions[i];
            ArrayAppend( existingTransactions, item );
        }

        var result = {};
        result.transactions = serializeTransactions;

        result.timestamp = newTimestamp;
        this[ "id#id#" ] = existingTransactions;;

    </cfscript>

    <cfreturn result>
</cffunction>

When a poll request completes, any new transactions are processed and a new poll is requested.

ApplicationController.prototype.getRequestSuccessFunction = function() {
<pre>	var self = this;
	return function( data, textStatus, jqXHR ) {

		var result = eval( "["+data+"]" );
		if ( result.length > 0 )
		{
			var transactions = result[0].TRANSACTIONS;
			self.lastTimeStamp = parseInt( result[0].TIMESTAMP );
			self.processTransactions( transactions );
		}

		self.pendingTransactions = [];
		self.requestPoll();
	}
}

You can access the full client and server application source on Github at:

I used ColdFusion in this example, however the server side could be written in any server-side language… Java, PHP, .NET, etc…

If you were building this application using web sockets, you could simply push the data across the socket connection without the need for queueing.