Tour de Flex expanded to include mobile samples!

•January 27, 2011 • Leave a Comment

Tour de Flex now has a bunch of new mobile samples!   This brings Tour de Flex to 609 total samples!  If you haven’t checked out Tour de Flex lately, you should.

Holly Schinsky wrote a blog post with more details on the new samples.

If you are ready to try your first mobile app in Flex, I suggest you grab Adobe AIR Launchpad and Tour de Mobile Flex.  They are the perfect next steps.

My photography appeared in a Discovery Channel documentary!

•January 23, 2011 • 1 Comment

Back in 2008, I shot a picture of the London Parliament from the London Eye during the evening hours of a cloudy day.  As with most of my photography, both personal and professional (aerial photography mainly), I posted it to SmugMug.  A few months later, I received a call from a producer who was doing work on a Discovery Channel documentary on Nostradamus.  He explained the price they were willing to pay for the use of my image for a few seconds in their upcoming film.  He went on to explain the rights they needed, the duration of the rights, blah  blah blah.  When he finished, I simply said, “You had me at ‘Discovery Channel'”.  Many months went by and I nearly forgot about it, but this weekend, I finally learned what documentary it was featured in — “Nostradamus Decoded“.  It’s a bit of a dooms-day flick, but hey!, it’s Discovery Channel!

Below is my original image (high-res version here) and a screenshot from the Discovery Channel use of it.  If you want to see how it appears, I found the entire film on YouTube in 9 parts.  Go to part 8 ( http://www.youtube.com/watch?v=CghrRuC2ROA ) and advance it to the 5:00 mark and wait a few secs.  Don’t look away or you’ll miss my 5 seconds of glory.

Many of you probably just rolled your eyes, but that’s too bad, I’m blogging it anyways!  😉

My original image:

Discovery Channel version (they edited it to make London look flooded and more gloomy):

Future conversations with me about photography will go something like this:

Stranger: Are you into photography?

Greg: Yes I am, I’ve even done some work for The Discovery Channel

😉

Gogo Inflight Internet now severely downgrading images automatically

•January 14, 2011 • 2 Comments

I am a HUGE fan of Gogo Inflight Internet on Delta.   We all remember the first time we tweeted or IM’d from 30,000 feet.  It’s almost magical!  The past 13 flights on Delta have had Gogo service so I’m now super spoiled.  I’m even posting this article from my flight!

BUT, now I have my first real complaint.  Very recently, Gogo has started severely compressing images during transmit.  Every image I see on the Internet has horrible artifacts as if someone saved it with the lowest quality setting.  I completely understand the intent – they want to preserve bandwidth, but there is something fundamentally wrong with web content being manipulated from it’s original form.  If I go to a web page, I should receive the web page as the author intended, not an auto-reduced version of it.  I’d prefer Gogo to raise their prices to reduce the number of people accessing their service instead of stripping the bits I receive.

Below is an example of what I’m talking about.  I shot this picture about two hours ago and uploaded it to SmugMug (what a sunrise!).  At first, I thought I had made a horrible mistake on the export, but then I quickly figured out what was going on.  If you are using Gogo now, you won’t see a difference between the top and bottom images.

The top image is taken from a screenshot of what I see in the browser when I go to the gallery.  The bottom image is the original image resized to match.

Every website I’ve tried has the same issue.  It even makes CNN look bad.

I know, I know, I’m spoiled.  I have wifi in the sky and now it’s not enough.  I’ll wait another few months before I ask for 20Mbps service 😉

UPDATE: Another bad side effect is that your cache will be filled with these downgraded images.  Now that I’m home I was still seeing poor quality images until I cleared my cache.

Getting started with Flex on mobile devices and tablets

•December 3, 2010 • 1 Comment

If you are an Adobe Flex developer and haven’t dipped your toe into the world of building mobile applications, skip your next lunch break and check it out!  It is incredibly fun and the resulting apps are impressive.  Because the tooling and SDK to make mobile app development with Flex possible is all in pre-release, finding information on how to get started can be a bit challenging, so I decided to create a quick guide for you.

Tooling up:

  • Get the preview release of Flash Builder Burrito from http://labs.adobe.com/technologies/flashbuilder_burrito/ – You can keep your existing Flash Builder install for your “day job” development and use the pre-release/Burrito install for your mobile fun.  It includes the required Flex SDK (code name Hero) so it’s really all you need from a Flex point of view.
  • Get an Android device running Froyo/Android 2.2.  If you don’t have access to a device, don’t let that stop you.  Flash Builder will run the app in an emulator.
  • Grab the latest version of Adobe AIR Launchpad from http://labs.adobe.com/technologies/airlaunchpad/ – Launchpad is a new desktop tool that helps Adobe Flex developers get started building AIR apps, including AIR for mobile apps.  This app will basically build a skeleton app for you with sample code for all of the fun mobile APIs (accelerometer, GPS, camera, etc.).  It will save you a ton of time learning.
  • If you have a device running Android 2.2, go to the Android Marketplace and install “Tour de Mobile Flex”.  You’ll find a QRcode to the app and the full source code at http://flex.org/tourmobile.  This is a great tool for exploring what is possible with Flex on mobile.  There are tons of running samples with full source.

Getting educated:

The current version of Flash Builder/Burrito supports Android devices.  Support for other platforms is coming soon.  You can even deploy your resulting apps in the Android Marketplace (you’ll need to pay $25 to sign up for the Android developer program at http://developer.android.com/).

UPDATE:  Christophe just posted a video of him running the employee directory application covered in his tutorial on 3 devices – Google Nexus One, Samsung Galaxy Tab and the RIM BlackBerry PlayBook (emulator)! — http://coenraets.org/blog/2010/12/deploying-a-flex-application-to-the-blackberry-playbook-and-android-devices/

Good webcam choice for mobile device demos on stage – IPEVO Point 2 View

•November 23, 2010 • 2 Comments

For the past few months, our team has been showing more and more applications running on various mobile devices.  We found out quickly that this is a real challenge on stage and even more challenging on web conferences.  Sure, we can run emulators, but people always want to see the real app running on a real device.

After trying multiple different camera options, we’ve found a great one, the IPEVO Point 2 View USB camera — http://www.ipevo.com/Point-2-View-USB-Camera_p_70.html

There are a few things that make this uniquely qualified for our needs:

  • The camera can be set to manual focus and then focused from the UI with a single mouse click.  Auto-focus cameras don’t work well because they will always focus on the nearest object in view…so when your finger moves into the frame, the focus is suddenly on your knuckle!  Manual focus is a must.  If you switch from one device to another, the ability to single-click refocus is awesome.
  • The included software has settings to flip the image either vertically or horizontally so getting the orientation correct is a piece of cake.
  • The software has the ability to set exposure compensation, which can be a big deal on some devices.  I found that by setting the exposure compensation to -2, the image is much more crisp.
  • The base is heavy enough to support the camera at just about any angle.
  • It’s portable enough to fit into my computer bag.
  • The image quality is good.

Negatives:

  • The various UI settings are not remembered from session to session.
  • Evidently, the base of the camera looks interesting in an x-ray machine.  On two different occasions, airport security did a manual check of the bag after running it through the machine.  I now take it out of the bag and lay it next to my laptop.

As of this writing, you can grab one for about $70 from Amazon — http://www.amazon.com/IPEVO-Point-View-USB-Camera/dp/B002UBPBTC

UPDATE:  A few folks have suggested this case for the cam — http://www.ipevo.com/Carrying-Case-for-P2V-USB-Document-Cam_p_97.html

TIP: Set the resolution to 800×600 to get a better framerate.

How to move Adobe AIR for Android to your SD card

•October 9, 2010 • Leave a Comment

If you are like me and have an android phone that is lacking internal RAM, you are probably doing a lot of app juggling to make it all fit.  Serge Jespers recent blogged: Android – Move your apps to SD where he explains how to move almost any app to the SD card.  This also allows you to move Adobe AIR for Android to the SD card. Keep in mind that the SD card is typically slower than internal memory, so you will pay a small price in load time so I highly recommend that you keep AIR in internal memory if possible. On my own Google Nexus One, it works well with hardly any load time increase at all.

Distributing content world wide using Amazon CloudFront

•October 5, 2010 • 3 Comments

A few days ago, I announced that many of the samples in Tour de Flex are now hosted in 16 distributed locations.  As promised, here are the details:

Prior to last Friday, most of the Tour de Flex samples were hosted from a dedicated server in California.  For those of us in the US, the load time for these samples was good, but for users in Europe and Asia, there were noticeably slower download times.   Lately, I’ve been playing around with Amazon EC2 and other Amazon web services and discovered a fairly new service called Amazon CloudFront, a web service for distributed content delivery.   In less than an hour, I had the Tour de Flex samples hosted from 16 edge servers across the globe:

All of the samples are now hosted on samples.tourdeflex.com, which is dynamically redirected by Amazon to the nearest edge server to the user.  For example, when I access samples.tourdeflex.com from my home in Tampa, I get directed to the Miami edge server.  Here’s my traceroute:

/Users/admin $ traceroute samples.tourdeflex.com
traceroute: Warning: samples.tourdeflex.com has multiple addresses; using 216.137.47.148
traceroute to d1icesobeldsjy.cloudfront.net (216.137.47.148), 64 hops max, 52 byte packets
 1  192.168.1.1 (192.168.1.1)  0.875 ms  0.623 ms  0.573 ms
 2  l5003.tampfl-vfttp-02.verizon-gni.net (71.251.98.1)  3.846 ms  4.139 ms  5.080 ms
 3  p15-1.tampfl-lcr-04.verizon-gni.net (130.81.59.42)  5.036 ms  3.919 ms  5.892 ms
 4  so-6-0-0-0.tpa01-bb-rtr2.verizon-gni.net (130.81.29.53)  7.424 ms  6.787 ms  8.721 ms
 5  ge-1-0-0-0.atl01-bb-rtr2.verizon-gni.net (130.81.17.48)  28.346 ms  29.175 ms  27.396 ms
 6  0.xe-8-1-0.br3.atl4.alter.net (152.63.80.209)  24.960 ms  24.046 ms  24.922 ms
 7  xe-11-3-0.edge4.atlanta2.level3.net (4.68.62.21)  27.255 ms  26.675 ms  28.086 ms
 8  * ae-62-51.ebr2.atlanta2.level3.net (4.68.103.29)  34.805 ms
    ae-72-52.ebr2.atlanta2.level3.net (4.68.103.61)  26.122 ms
 9  ae-2-2.ebr2.miami1.level3.net (4.69.140.141)  44.494 ms  47.026 ms  37.952 ms
10  ae-2-52.edge1.miami2.level3.net (4.69.138.107)  50.364 ms  41.447 ms  42.235 ms
11  amazoncom.edge1.miami2.level3.net (4.59.80.38)  42.755 ms  42.136 ms  42.491 ms
12  server-216-137-47-148.mia3.cloudfront.net (216.137.47.148)  42.543 ms  42.823 ms  41.503 ms

I’m hoping that Amazon adds a few edge servers in South America, South Africa and Australia soon.

Getting this working was amazingly simple:

The cost:

The pricing is simple.  Depending on the edge server location, Amazon charges between 15 and 20 cents per GB of data transferred and about a penny for every 10,000 file transfers.  Below is the bill for nearly 5 days of Tour de Flex sample serving to give you an idea of how things work:

As you can see, it’s not bad!  It’s costing us less than $1/day!  For more details on pricing, go to http://aws.amazon.com/cloudfront/pricing/

Tooling:

For my project, I needed a way to easily transfer thousands of files to my S3 bucket.  I also needed a way to easily flag a file for redistribution to the edge servers, which is required when we update a sample.  Amazon calls this process “file invalidation”.  It basically forces the file to be redistributed to the edge servers.  It’s like clearing the cache for a specific file or group of files.  The Amazon web interface does not provide the ability to invalidate a file yet, so I had to find a tool.  For Mac OS X, Windows and Linux, there is Bucket Explorer (http://www.bucketexplorer.com/) that provides everything needed.  Another good Windows option is CloudBerry Explorer (http://cloudberrylab.com/).  CyberDuck (http://cyberduck.ch/ – open source) for Mac OS X comes close but is missing file invalidation.

There is a great Linux command line tool for syncing folders with S3 called S3 Tools (http://s3tools.org/s3cmd) but it doesn’t yet support CloudFront file invalidation.

Flex/Flash, AIR and Amazon CloudFront

This is a great service for Flex/AIR developers because it provides a way to distribute our application and assets more efficiently.  I have also used CloudFront  for my side project, ChessJam.   I use it for the 7MB AIR file downloads and for the web version of ChessJam.  For the web version, I moved the SWF and all needed assets (images, audio files, etc.) to my CloudFront server.  Several users in Asia and Europe noticed an immediate improvement in load times.  For about 90 cents per day, I get happier users!  Nobody likes waiting on preloaders and lengthy downloads.

Tour de Flex Samples now hosted in 16 locations across planet earth

•September 30, 2010 • 4 Comments

A few weeks ago, Tour de Flex passed the 20 million samples served milestone very quietly.  The quietness was not intentional…. we were just too busy to notice when it happened!  Traffic continues to be very strong and very spread out across the globe.  Starting a few minutes ago, all of the Tour de Flex samples are now hosted in 16 different locations around the world (see map below).  When you view a sample, it will load from the location that is closest to you.  If you are in China or Japan, you’ll really see a difference in load times.

I’ll be blogging in the next couple of days on how this was accomplished in less than two hours….so stay tuned.  It’s actually very cool!

For those of you that haven’t looked at Tour de Flex lately, you should take a fresh look.  We now have 551 Flex samples!  A lot of the credit goes to Maile Valentine who has taken over responsibilities for getting more samples deployed to Tour de Flex.  Our response time has gone from 8+ weeks (I suck) to less than 2 days (Maile rocks)!   SO IF YOU HAVE SAMPLES TO CONTRIBUTE, SEND THEM TO ME at gregsramblings (at) gmail (dot) com.  After a quick review, Maile will get them added.

Below is a map showing the servers:

MAX Session: New LiveCycle Data Services Support for HTML5/JS, Native Android, Apple iOS, Java, and .NET

•September 26, 2010 • 5 Comments

We just added a new session to MAX — New LiveCycle Data Services Clients: HTML5/JavaScript, Native Android, iPhone/iOS, Java, and .NET — Tuesday, October, 26th, 4:30 pm – 5:30 pm

Get a preview of our upcoming Adobe LiveCycle Data Services client capability for HTML5/JavaScript, Java, native Android apps and Apple iOS (iPhone/iPad).  I’ll also be previewing new server support for .NET! LiveCycle Data Services is not just for Flex clients anymore. Explore how developers can now use remoting and messaging to write multiclient, multiserver apps.

Summary:  Some cool announcements will be made in this session!  BE THERE!

My dive into the world of Amazon EC2 and the new crazy cheap Micro instance

•September 22, 2010 • 9 Comments

I heard about Amazon EC2 when it launched in 2006 but had never really checked it out until about four weeks ago when I was looking for at my options for hosting some demos that require more control over the machine than what a typical hosting company provides.  One of my fellow evangelists, James Ward, gave me a one hour tour of EC2 and educated me on the sometimes confusing terminology that EC2 experts take for granted.  Things like “elastic IP”, “AMIs”, “instances”, “spot instances”, “reserved instances”, “CPU units”, etc.  It’s a bit intimidating and confusing at first glance, but it quickly comes into focus. I then talked to another co-worker Marcel Boucher who is deeply involved in LiveCycle Express, our EC2-based cloud offering of LiveCycle ES2 and got some more real-world knowledge on EC2.

I don’t think the 4 or 5 hours I’ve invested in learning EC2 qualifies me as an expert, so I’m not proposing that this video is a “tutorial”.  There are plenty of good tutorials that I’ll point you to below.  However, I am excited about what I’ve learned and thought that readers would enjoy a 10 minute briefing that will give you a good sampling of what EC2 is all about.  Not everyone has EC2 experts on speed dial so here’s the next best thing.  The gadget guy in me loved this experience.  It’s like going to the computer store, buying a bunch of hardware to play with and returning it at the end of the day.  You can literally spend an entire day playing with EC2 for less than $1!

Below is a video I recorded that walks through a brief explanation of EC2 and walks through a live demo of creating a new instance from scratch, setting up security, starting the instance, logging in and installing Apache.  I go from nothing to a public facing ready to go server in the cloud in 6 minutes.

The links in the video can be found at http://gregsramblings.com/ec2

UPDATE 09/29/2010:

I’ve had my instance up and running for 11 days. Below is my bill so far for 11 days:

ec2 price micro

LiveCycle ES2 described by Avoka

•September 14, 2010 • Leave a Comment

Howard Treisman, Technical Director at Avoka, recently wrote a blog post titled, “LiveCycle in an Elevator“, a very good “elevator pitch” of the multiple facets of LiveCycle.

Avoka has customers in the USA, Europe and Australia.  They have many LiveCycle and Flex gurus that build customer solutions as well as some killer products.  Check them out.

Adding real-time data visualization to your ColdFusion apps

•September 8, 2010 • 1 Comment

One of my favorite things to do with Adobe Flex is build applications that  show real-time data. In this blog post, I will share what I’ve learned in the past few months about using ColdFusion as a source of real-time data and Flex combined with Google Maps API for Flash as a means of visualizing the data. The live map below is an example of what you can build using this technique. (If you can’t see the live map, you need to make sure you have Flash enabled). The map you see is a real-time view of activity on several blogs including my blog as well as blogs by James Ward, Christophe Coenraets, Michael Chaize, Anne Petteroe, Holly Schinsky, Ted Patrick, Kevin HoytRyan Stewart, Ray Camden and also hits to Flex.org. Every time one of these sites is viewed by someone, a dot appears on the map at their approximate location.  Give it a shot!   I’ll let you figure out which color marker goes with each blog.  Go hit one of the blogs or Flex.org and see yourself on the map (assuming your IP address is mappable). There is also a “LOAD LAST HOUR” button if you want to replay the last hour in accelerated time. Below is everything you need to add this type of visualization to any website or application.

Vodpod videos no longer available.

Technologies used in this application:

  • ColdFusion 9.01 standalone running on port 8500 — fresh out-of-the-box install on Windows 7 (will also work with ColdFusion 8 ) — this blog post assumes that ColdFusion is installed at C:\ColdFusion9.
  • BlazeDS 4 (included with ColdFusion 9.01 – also works with BlazeDS 3 and LiveCycle Data Services)
  • Flex SDK 4.1 (all of this will work with Flex 3.x or Flex 4.0 too with minor changes)
  • Flash Builder 4
  • ColdFusion Builder

Introduction to publish/subscribe messaging

The easiest way to tap into real-time data is to employ a messaging paradigm called publish/subscribe messaging (commonly called “pub/sub”).  The website/blog activity is published to a message destination as small messages.  Below we will write some ColdFusion code that publishes data and then we will write some Flex code that subscribes to these published messages and does fun things with them.

Publishing messages with ColdFusion

ColdFusion uses the sendGatewayMessage() function to publish messages.  Before we can use this nifty function, we need to first configure a data service messaging gateway instance.

  1. Go to ColdFusion administrator and go to the Gateway Instances option under EVENT GATEWAYS.
  2. Create a new gateway instance using the gateway type “DataServicesMessaging“.
    1. For this example, I used “cfgw” as the name of our new gateway ID.
    2. For now, just point the CFC PATH to any CFC. By creating an “onMessage()” function, ColdFusion can receive messages through the gateway but for this article, we’re only going to focus on sending messages so it’s not necessary to have this function.
    3. The configuration file already exist in your default installation at C:\ColdFusion9\gateway\config\flex-messaging-gateway.cfg.
    4. IMPORTANT: You’ll need to edit the following config file (C:\ColdFusion9\gateway\config\flex-messaging-gateway.cfg) and comment out the line: host=”localhost” (see the comments in the flex-messaging-gateway.cfg for an explanation).
    5. Click “Add Gateway Instance” to save your work.
  3. Restart ColdFusion – check the cfserver.log for any gateway-related errors.

Now we can use the sendGatewayMessage() function to broadcast data.  The code below publishes a simple struct that contains “Hello World” in the body.

<cfset msg= structNew()/>
<cfset msg['destination']	= "ColdFusionGateway"/>
<cfset msg['body']       	= "Hello World"/>
<cfset sendGatewayMessage("cfgw",msg)/>

Notice the sendGatewayMessage() function uses our recently created “cfgw“.  Also, notice the ‘destination‘.  In this example, we are using the preconfigured destination called “ColdFusionGateway“.  If you want to see the definition of this destination, check out the following two files:

  • c:\ColdFusion9\wwwroot\WEB-INF\flex\messaging-config.xml — defines messaging destinations – you’ll see “ColdFusionGateway” already defined.  Near the bottom of the definition is a section for configuring the communication channel:
    <channel><channel ref=”cf-polling-amf”/></channel>
    The “cf-polling-amf” channel is defined in the services-config.xml file.
  • c:\ColdFusion9\wwwroot\WEB-INF\flex\services-config.xml — defines the individual services.

We’ll talk more about these configuration files later.

Now we have some simple ColdFusion code that publishes messages.  Next, we need to build something to consume them!

Subscribing to messages using a Flex Consumer

Below is a very basic Flex application that will subscribe to the same destination that we used above, “ColdFusionGateway”.   To try this out, simply create a new Flex project and copy the code below into the main mxml file.  Don’t worry about selecting an application server in this sample because we’re defining everything in the code.  For me, it’s just easier to understand when everything is in front of me rather than wired into a properties file somewhere.

</span>
<pre><?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   applicationComplete="init()">
	<fx:Script>
		<![CDATA[
			import mx.controls.Alert;
			import mx.messaging.events.ChannelEvent;
			import mx.messaging.messages.IMessage;

			private function init():void
			{
				consumer.subscribe();
			}

			private function onMessage(message:IMessage):void
			{
				trace("Message received:" + message.body);
				log.text += message.body + "\n";
			}

			private function onChannelConnect(e:ChannelEvent):void
			{
				trace("Connected!");
				log.text += "Channel connected!\n";
			}

			private function onChannelDisconnect(e:ChannelEvent):void
			{
				trace("Disconnected!");
				log.text += "Channel disconnected!\n";
			}
		]]>
	</fx:Script>
	<fx:Declarations>
		<mx:ChannelSet id="channelSet">
			<!-- Default Polling Channel -->
			<mx:AMFChannel url="http://192.168.1.60:8500/flex2gateway/cfamfpolling"/>
		</mx:ChannelSet>

		<mx:Consumer id="consumer"
			 channelSet="{channelSet}"
			 destination="ColdFusionGateway"
			 resubscribeAttempts="-1"
			 resubscribeInterval="2000"
			 message="onMessage(event.message)"
			 channelConnect="onChannelConnect(event)"
			 channelDisconnect="onChannelDisconnect(event)"
			 fault="Alert.show(event.faultString)"/>

	</fx:Declarations>
	<s:TextArea id="log" width="100%" height="100%"/>

</s:Application>

The only thing you’ll need to change is the IP address in the ChannelSet to point to your ColdFusion server.  I have event handlers that fire when the app successfully connects to the server, when a message is received and when the app gets disconnected from the server.  When you first run the app, after a few seconds, you should see the “Channel Connected!” message.  Now you can run the CF code above to send the “Hello world” message and you should see it received into your Flex application.  It might take a few seconds due to the type of channel we are using.  We will improve the response time later by creating our own custom channel definition.

Adding coolness step 1: Getting the IP address and converting to location

Now that you know how to publish data from ColdFusion and consume that data from a Flex application, it’s easy to build some really cool stuff.  First, we need to add some additional data to our outbound message from ColdFusion.

Getting the IP address in ColdFusion is super easy.  It’s already available to you in #CGI.REMOTE_ADDR#.  There are several services that provide IP address to location conversion but my favorite way to do it is to use a local database from MaxMind, a provider of geolocation and online fraud detection tools.  The conversion is lightning fast because the database is right on my server.  They have several databases available, but I highly recommend using one of the following:

MaxMind provides APIs for C, C#, Perl, PHP, Java, Python, Ruby, VB.NET, Pascal (huh?), and JavaScript.   Since Java is in the list, it’s easy to get this working with ColdFusion as well.  Thankfully, I didn’t have to do any work on this because Brandon Purcell has done it for us!  Brandon provides step-by-step instructions in his blog post.  To summarize Brandon’s steps, you download a JAR file that he created, copy it to your C:\ColdFusion9\runtime\servers\lib folder (CF restart required), add some code to your Application.cfc (example provided in Brandon’s post), and put the included geo.cfc file in your application folder.

Now we can do this:

<cfinvoke component="geo" method="ipLookup" returnVariable="location">
	<cfinvokeargument name="IP" value="#CGI.REMOTE_ADDR#"/>
</cfinvoke>

<cfset geodata = structNew()/>
<cfset geodata['destination']		= "ColdFusionGateway"/>
<cfset geodata['body']['city'] 		= "#location.IPCITY#"/>
<cfset geodata['body']['country'] 	= "#location.COUNTRYLONG#"/>
<cfset geodata['body']['countryshort']	= "#location.COUNTRYSHORT#"/>
<cfset geodata['body']['latitude'] 	= "#location.IPLATITUDE#"/>
<cfset geodata['body']['longitude'] 	= "#location.IPLONGITUDE#"/>

<cfset sendGatewayMessage("cfgw",geodata)/>
<cfdump var="#geodata#"/>

Notice that I added a <cfdump/> to the end so I can see the results.  It’s very likely that if you run the code above, it will not show a location because your IP address is probably a private one since you are in the same subnet as your server.  To test, I put in my public IP address in place of #CGI.REMOTE_ADDR# and got the following:

Now we’re getting somewhere!  The message we are broadcasting now contains city, country (two formats), latitude, and longitude.  We can extract these new fields on the Flex side by referencing message.body.city, message.body.country, message.body.countryshort, message.body.latitude, and message.body.longitude.

Adding coolness step 2: Mapping the location

Now that we have lat/long, we can use many different mapping services.  You’ll find examples of Google, ESRI, MapQuest and Yahoo! Maps in Tour de Flex under the mapping category.  For this blog post, I’m using the Google 3D Maps API for Flash.  You’ll find many other Google Maps-related APIs at http://code.google.com/apis/maps.

I decided to use the 3D Map APIs for this because it allows you to change the map attitude, pitch, and yaw, which is a lot of fun and always impresses.

Steps to get this working:

  1. Go to http://code.google.com/apis/maps/documentation/flash and sign up for a Google Maps API Key (takes less than a minute and it’s free).
  2. Create a new Flex project like the one above (no special options, app server, etc. — just a plain ol’ Flex project).
  3. Download the Google Maps API for Flash SDK from the same page.  The ZIP file contains documentation and the map_flex_1_18b.swc that you need to place in your Flex project’s libs folder. (As of this writing the version was 1.18b; your SWC filename may vary.)
  4. Use the code below as your main mxml file.
  5. Don’t forget to modify the IP address in the <ChannelSet/> to point to your ColdFusion server.
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   xmlns:maps="com.google.maps.*"
			   width="100%" height="100%">

	<fx:Script>
		<![CDATA[
			import com.google.maps.InfoWindowOptions;
			import com.google.maps.LatLng;
			import com.google.maps.Map3D;
			import com.google.maps.MapEvent;
			import com.google.maps.MapOptions;
			import com.google.maps.MapType;
			import com.google.maps.View;
			import com.google.maps.controls.MapTypeControl;
			import com.google.maps.controls.NavigationControl;
			import com.google.maps.geom.Attitude;
			import com.google.maps.overlays.Marker;
			import com.google.maps.overlays.MarkerOptions;
			import com.google.maps.styles.FillStyle;

			import mx.controls.Alert;
			import mx.messaging.events.ChannelEvent;
			import mx.messaging.messages.IMessage;

			private function onMapPreinitialize(event:MapEvent):void
			{
				// Before the maps is rendered, we set a bunch of options
				var myMapOptions:MapOptions = new MapOptions();
				myMapOptions.zoom 		= 3.5;
				myMapOptions.center 	= new LatLng(10,-30);
				myMapOptions.mapType 	= MapType.SATELLITE_MAP_TYPE;
				myMapOptions.viewMode 	= View.VIEWMODE_PERSPECTIVE;
				myMapOptions.attitude 	= new Attitude(0,30,0);
				myMapOptions.backgroundFillStyle = new FillStyle({color: 0x000000, alpha: 1.0}),

				map.setInitOptions(myMapOptions);
			}

			private function onMapReady(event:MapEvent):void
			{
				map.addControl(new MapTypeControl());    // selection of map, satellite, hybrid and terrain
				map.addControl(new NavigationControl()); // Controls for pan, zoom, attitude

				consumer.subscribe();	// Start receiving messages now that the map is ready
			}

			private function onMessage(message:IMessage):void
			{
				var city:String			= message.body.city;
				var country:String 		= message.body.country;
				var countryshort:String = message.body.countryshort;
				var latitude:String		= message.body.latitude;
				var longitude:String	= message.body.longitude;

				// Sometimes the city and/or country come back blank.  I prefer "Unknown"
				if(city == "") city = "Unknown";
				if(country == "") country = "Unknown";

				var location:String		= city + ", " + country;

				// We need a LatLng object for use with the map
				var latlng:LatLng = new LatLng(message.body.latitude, message.body.longitude);

				// If the latitude/longitude is populated, go place the marker and an info window
				if(latlng != null)
				{
					// Customize our marker a bit (tons of options are available including a custom icon
					var markerOpts:MarkerOptions = new MarkerOptions();
					markerOpts.tooltip = location;
					markerOpts.radius = 5;
					markerOpts.fillStyle = new FillStyle({color:0xff0000});

					// Create a new marker with our customizations
					var marker:Marker = new Marker(latlng,markerOpts);

					map.addOverlay(marker);  // Add our new marker to the map

					// Customize the popup info window
					var infoWindowOpts:InfoWindowOptions = new InfoWindowOptions();
					infoWindowOpts.titleHTML = location;
					infoWindowOpts.contentHTML = latitude.substr(0,6) + "," + longitude.substr(0,6);
					infoWindowOpts.fillStyle = new FillStyle({alpha:0.5});

					map.openInfoWindow(latlng,infoWindowOpts); // Add the info window
				}
				trace("Message received from " + location);
			}

			private function onChannelConnect(e:ChannelEvent):void
			{
				trace("Connected!");
			}

			private function onChannelDisconnect(e:ChannelEvent):void
			{
				trace("Disconnected!");
			}
		]]>
	</fx:Script>

	<fx:Declarations>
		<mx:ChannelSet id="channelSet">
			<!-- Default Polling Channel -->
			<mx:AMFChannel url="http://192.168.1.60:8500/flex2gateway/cfamfpolling"/>
		</mx:ChannelSet>

		<mx:Consumer id="consumer"
					 channelSet="{channelSet}"
					 destination="ColdFusionGateway"
					 resubscribeAttempts="-1"
					 resubscribeInterval="2000"
					 message="onMessage(event.message)"
					 channelConnect="onChannelConnect(event)"
					 channelDisconnect="onChannelDisconnect(event)"
					 fault="Alert.show(event.faultString)"/>
	</fx:Declarations>

	<maps:Map3D id="map"
				mapevent_mappreinitialize="onMapPreinitialize(event)"
				mapevent_mapready="onMapReady(event)"
				width="100%" height="100%"
				key="PUT-YOUR-GOOGLE-API-KEY-HERE"/>

</s:Application>

Run the new Flex app and every time your ColdFusion code broadcasts a new activity message, it will extract the location from the message and display it on the Google 3D map.

You’ll find tons of fun features including the ability to “fly” to a new location, customize markers and more at http://code.google.com/apis/maps/documentation/flash/reference.html.   There are tons of other demos available at http://code.google.com/apis/maps/documentation/flash/demogallery.html

Adding coolness step 3: Using the <IMG> tag

When I first started playing with this stuff, I was eager to add tracking to my own blog so I could watch my blog activity on a world map, but, my blog is not ColdFusion based so I didn’t have the luxury of adding a few lines of ColdFusion code to broadcast the needed data.  There are several server-side options that could work but my blog is hosted at WordPress.com so my options were very limited.  I don’t even have access to the server!  Late one night I had a crazy idea — I would use the <IMG> tag!  It’s the most common way external assets are included in HTML.

With a little help from Ray Camden, I figured out how to get a CFM file to behave like an image.  On my blog, I simply have an image as follows:  <img src=”http://myserver.com/trackimg.cfm&#8221; width=”1″ height=”1″>.   Web browsers think it’s a 1×1 transparent png.

Here’s the source to trackimg.cfm:

<cfsetting enablecfoutputonly="Yes">
<cfsetting showdebugoutput="No">

<cfinvoke component="geo" method="ipLookup" returnVariable="location">
	<cfinvokeargument name="IP" value="#CGI.REMOTE_ADDR#"/>
</cfinvoke>

<cfset geodata = structNew()>
<cfset geodata['destination']			= "ColdFusionGateway">
<cfset geodata['body']['city'] 			= "#location.IPCITY#">
<cfset geodata['body']['country'] 		= "#location.COUNTRYLONG#">
<cfset geodata['body']['countryshort']	= "#location.COUNTRYSHORT#">
<cfset geodata['body']['latitude'] 		= "#location.IPLATITUDE#">
<cfset geodata['body']['longitude'] 	= "#location.IPLONGITUDE#">

<cfset sendGatewayMessage("cfgw",geodata)>

<!--- Read a 1x1 transparent png from disk that I created in photoshop --->
<cffile action="readBinary"
	file="c:\ColdFusion9\wwwroot\images\dot.png"
	variable="trackImage">

<!--- Return the 1x1 bitmap in png format --->
<cfheader name="content-disposition" value="Inline;filename=dot.png">
<cfcontent type="image/png;" variable="#trackImage#">

Now I can add tracking to any website I desire by simply adding the image tag.  In my demo app at the top of this blog post, you’ll notice that different sites show up as different colors.  I simply do this by adding a “color” variable to my geodata struct.  I set the color based on the domain in the referrer (#CGI.HTTP_REFERRER#) using code like this:

<cfelseif findNoCase("gregsramblings.com",#CGI.HTTP_REFERER#)>
	<cfset color="EEEE00">
	<cfset domain="gregsramblings.com">
<cfelseif findNoCase("flex.org",#CGI.HTTP_REFERER#)>
	<cfset color="00FF00">
	<cfset domain="flex.org">
<cfelseif findNoCase("jamesward.com",#CGI.HTTP_REFERER#)>
	<cfset color="9933FF">
...
...
<cfset geodata['body']['color']  = "#color#">
<cfset geodata['body']['domain'] = "#domain#">
<cfset geodata['body']['url']    = "#CGI.HTTP_REFERER#">
...
...

On the Flex side, I use message.body.color to set the marker color.  I use message.body.domain and message.body.url in the info window. There are lots of possibilities.

Geting Technical — Using messaging subtopics

All of the Flex code in this article is set up to receive all messages sent from the ColdFusion server.  If you later want to use the same ColdFusionGateway for multiple applications, you’re going to need some way to filter messages.  This is where subtopics come in.  Subtopics provide a means of categorizing messages within a destination.  By default, subtopics are enabled as you can see near the top of C:\ColdFusion9\wwwroot\WEB-INF\flex\messaging-config.xml.   To publish messages on a specific subtopic, add the following to your struct: <cfset geodata[‘headers’][‘DSSubtopic’] = “BLOGS”>.  On the Flex side, we add subtopic=”BLOGS” to our <mx:Consumer>.  Now our Flex app will only receive messages sent specifically on the BLOGS subtopic.  Subtopics can be defined as mainToken[.secondaryToken][.additionalToken] so you could use something like “BLOGS.GREG” for one site and “BLOGS.BEN” on another.  On the Flex side, you can subscribe to either or you can use wildcards to subscribe to multiple subtopics  – subtopic=”BLOGS.*”.   When you subscribe to a subtopic, the filtering happens at the server, so your app only receives messages that match.

In addition to subtopics, you can also use selectors.  For more information on selectors and subtopics, refer to the BlazeDS documentation.

Getting Technical — Channel Types

You may have noticed that there is sometimes a delay of a few seconds after ColdFusion sends the message until the Flex app receives it.  So far we have been using the out-of-the box configuration for ColdFusionGateway.  If you look in the C:\ColdFusion9\wwwroot\WEB-INF\messaging-config.xml, you’ll see that the assigned channel is cf-polling-amf, which is defined in C:\ColdFusion9\wwwroot\WEB-INF\flex\services-config.xml.  This is set up to do basic polling, which is not super responsive.  We can speed things up significantly by implementing “long polling”.  Here are the steps:

1. Add the following channel definition to your C:\Coldfusion9\wwwroot\WEB-INF\services-config.xml:

<channel-definition id="cf-longpolling-amf" class="mx.messaging.channels.AMFChannel">
	<endpoint url="http://{server.name}:80/{context.root}/flex2gateway/amflongpolling" class="flex.messaging.endpoints.AMFEndpoint"/>
	<properties>
		<polling-enabled>true</polling-enabled>
		<polling-interval-seconds>3</polling-interval-seconds>
		<wait-interval-millis>60000</wait-interval-millis>
		<client-wait-interval-millis>1</client-wait-interval-millis>
		<max-waiting-poll-requests>200</max-waiting-poll-requests>
	</properties>
</channel-definition>

2. Edit the C:\ColdFusion9\wwwroot\WEB-INF\messaging-config and assign this new channel to the ColdFusionGateway destination. The modified XML will look like this:

<channels>
	<channel ref="cf-longpolling-amf"/>
	<!--<channel ref="cf-polling-amf"/>-->
</channels>

3. Modify your Flex code and change the URL of your ChannelSet:

<mx:ChannelSet id="channelSet">
	<!-- Default Polling Channel -->
	<mx:AMFChannel url="http://192.168.1.60:8500/flex2gateway/amflongpolling"/>
</mx:ChannelSet>

4. Restart ColdFusion and everything should work as before, but you’ll notice that messages get through faster.

Polling and Long Polling are not the only two options.  BlazeDS also supports HTTP Streaming, which has even better performance but some firewalls don’t like a persistent connection.  You can find more information about endpoints in Holly Schinsky’s blog post and in the documentation.

Getting Technical — What about LiveCycle Data Services?

LiveCycle Data Services ES2 (LCDS) offers the same messaging features as BlazeDS but it also has some additional capabilities that you need to be aware of.

  • RTMP: In addition to polling, long polling, and HTTP Streaming, LCDS provides Real Time Messaging Protocol (RTMP).  RTMP streams data in real-time over the TCP-based RTMP protocol in the binary AMF format.  It’s super fast and efficient and great for situations where you need thousands of subscribers to your message topics.  You can read more about channels and endpoints in LCDS here.
  • NIO-based endpoints:  Unlike BlazeDS endpoints, NIO-based endpoints are outside the servlet container and run inside an NIO-based socket server. NIO-based endpoints can offer significant scalability gains. Because they are NIO-based, they are not limited to one thread per connection. Far fewer threads can efficiently handle high numbers of connections and IO operations.  NIO-based endpoints are documented here.
  • Reliable messaging:  In LCDS, you can set a destination to be “reliable”.  Basically, LCDS will confirm that each message is received by all active consumers.  With non-reliable messaging, a short network outage could result in lost messages because there is no “retry” mechanism.  For applications like our activity tracking map, it’s no big deal..we just miss a dot on our map!  However, if you use messaging in an application where every message is critical, this is a key feature.  You can read more about it here.
  • Message throttling: Throttling is a feature that allows you to limit the number of server-to-client and client-to-server messages that a Message Service  destination can process per second.  Throttling is useful when the server could overwhelm slow clients with a high number of messages that they cannot process or the server could be overwhelmed with messages from clients.  You can read more about throttling here.

The full LCDS 3.1 documentation can be found at http://help.adobe.com/en_US/LiveCycleDataServicesES/3.1/Developing

Note:  I’ve only addressed the LCDS-specific features for messaging.  There are many other facets to LCDS that should not be ignored.  For messaging, it’s fairly simple.  If you need the features I just listed or if you need highly scalable messaging, then you need LCDS, otherwise BlazeDS will work for you.

What’s next with the real-time map app?

I’ve recently added server-side logging and the ability to replay history on the map (load last hour, load last day, etc.).  I’ve also added icons and other features.  I’ll do a new blog post showing the updated code in the next few days.

If you build something cool using the information in this blog post, I would love to see it.  I am dying to see a very high-traffic website on a map like this.

Here’s another example of real-time data on a map that I like to show — http://www.chessjam.com/online_chess_stats.cfm — what you will see is real-time activity from ChessJam, an online chess site that I helped develop.  The server is ColdFusion so I simply added code similar to what I show above in the function that handles chess moves.  Every time a player makes a move, it shows on the map.   I used an image of a map from 1812 as an overlay to give it a little age.  The really amazing thing here is that a map of the world could be made in 1812!  How did they do that with no GPS, no satellite pictures, etc.?  Crazy!

Enjoy!

Adobe AIR Launchpad – a tool for Flex developers building AIR applications

•August 23, 2010 • 17 Comments

During the past two years, I’ve met a lot of developers going through the process of learning to build desktop applications on Adobe AIR. As they learn AIR, these developers face the same set of challenges — enabling auto-update, setting up icons, creating an install badge, accessing the SQLite database, and using the many other AIR APIs. Even my own blog traffic is evidence of the many developers seeking information on building AIR apps.  For example, my blog post titled, “Adding auto-update features to your AIR application in 3 easy steps” has been read 19,828 times!  As I was thinking about all of this, I realized that we needed to figure out a way to help developers learn this stuff faster!

Today we launched Adobe AIR Launchpad, a desktop tool that helps Adobe Flex developers get started building desktop applications deployed on Adobe AIR. Simply run Adobe AIR Launchpad and select the capabilities you need; Adobe AIR Launchpad will create a ready-to-import Flex project with your selected features implemented in a way that can be easily modified and extended. You can use the resulting project as a starting point for your AIR application.

Adobe AIR Launchpad creates a folder structure that contains a ready-to-compile AIR application with the selected features implemented. It also creates a ZIP file in the parent folder that can be imported directly into Adobe Flash Builder. If you select auto update as an option, a “server” subfolder will be created that contains the XML file needed on the server to control auto-update. If you select the install badge option, a “install_badge” subfolder will be created containing the files needed to create an install badge.

The generated code is well commented and clearly written.  I think you will find that using this tool will dramatically accelerate learning AIR.

The Adobe AIR Launchpad is free and available now at http://labs.adobe.com/technologies/airlaunchpad

If you like Launchpad and have never looked at Tour de Flex, check it out at http://flex.org/tour – there are over 500 Flex samples including a lot of AIR-specific samples.

CREDITS:  Holly Schinsky (blog / twitter) built nearly all of the application including the generated code and comments.  Holly has a unique sense of what developers need when learning a new language or API.  Her blog has a large and growing following because her blog posts are very useful and written from one developer to another in a no-nonsense style.  Holly has often discussed building code templates that developers can use as a learning resource so this project was a perfect fit for her.   Christophe Coenraets, James Ward, Michael Chaize, Ben Forta and I contributed to the overall design and concept.

James Ward created a great demo video:

Michael Chaize also created a demo video:

The AIR Administrator’s Guide – controlling Adobe AIR in your environment

•August 5, 2010 • 1 Comment

Every day I see new applications that take advantage of all of the cool features that AIR provides such as SQLite database, encrypted DB, idle detection, network detection, local file support, socket support, native integration, etc.   It is no surprise that AIR is starting to be a logical choice for many enterprise applications, especially applications that need extra security, offline capabilities and strict control over the UI.

As enterprise IT administrators start getting requests for AIR applications to be deployed in their environments, they immediately start asking questions about how they can control the deployment, auto-updates, etc.

Many people are not aware that Adobe has an AIR Administrator’s Guide.  In this guide you’ll learn how to do the following:

  • Perform silent installs of the AIR runtime and AIR applications using Microsoft SMS, IBM Tivoli and other deployment tools
  • Prevent installation of additional AIR applications
  • Prevent installation of untrusted AIR applications
  • Disable automatic updates of the AIR runtime

You can download the guide in PDF format from http://help.adobe.com/en_US/air/admin/air_admin_guide.pdf or read it online here.

CFUnited Session: Building Multiplayer games on the Flash Platform with ColdFusion, Flex and Data Services

•July 26, 2010 • 4 Comments

On Thursday, I’m presenting a session at CFUnited titled, “Building Multi-Player games on the Flash Platform with ColdFusion, Flex and Data Services“.   As you can see, I’m trying to do something a bit more fun than my usual topics!   Yes, I’m talking about ColdFusion powering a multiplayer game!  Over the past 18 months, I’ve been involved in a fun weekend project called ChessJam with a couple of friends.  ChessJam is a multiplayer chess game that is seeing some incredible traffic over the past few months.  The entire app is powered on the back-end by ColdFusion.  The front-end is built in Flex and deployed on Adobe AIR.  This will be the first public sharing of any internals.  Even if you are not interested in building games, there are some techniques that I will share in this session that you will find useful in any collaboration application.

Topics:

  • Find out why we chose the technology stack:  Ubuntu Linux, MySQL, ColdFusion, LiveCycle Data Services, Flex, AIR
  • Learn how to use publish/subscribe messaging techniques to enable multi-player communications
  • Hear about the challenges we faced as we dealt with users in remote areas of the globe with poor networking conditions and how we addressed it (we have users from more than 200 countries)
  • Learn how to take advantage of ColdFusion remoting in Adobe Flex — soooo easy and soooo fast!
  • Explore various collaboration techniques employed throughout ChessJam from in-game chat to synchronized views

I’m really looking forward to presenting this session.  This project has been a lot of fun and I am excited to share.  To prepare for this session, go grab the app and play! — http://chessjam.com

CFUnited Session: 7/29 Thursday 4:00PM – 5:00PM Faulkner

CFUnited Session: Adding real-time data visualization to your application or website

•July 26, 2010 • 10 Comments

On Friday, I’m presenting a session at CFUnited titled, “Adding real-time data visualization to your application or website“.   In this session, I’m going to demonstrate how to take data from your web site or application and turn it into a real-time data feed that can be used to feed a dashboard that will impress your boss!  😉

Topics:

  • Explore multiple techniques to tap into your app/site’s activity data (swf, “magic png”, server-side, etc.)
  • Learn how to convert an IP Address to latitude, longitude, city and country
  • Use ColdFusion’s sendGatewayMessage() to broadcast the data
  • Learn how to configure publish/subscribe messaging using BlazeDS (included with CF9) and LiveCycle Data Services (I’ll explain the differences)
  • Learn how to build amazing data visualizations using Adobe Flex
  • Take a deep dive into two visualization examples:
    • Use Google Map Flash 3D APIs (amazing features)
    • Use IBM ILOG Elixir’s heat map component and gauges

I’ll be sharing the full source-code for the whole thing.

CFUnited Session: 7/30 Friday 3:15PM – 4:15PM Ballroom A

I hope to see you there!

Some fantastic demos of AIR on Android by Christophe Coenraets

•July 23, 2010 • 4 Comments

Over the past few weeks, Christophe Coenraets has been working some late nights experimenting with the various beta builds of AIR for Android.   As a result, he has created some cool applications and shared them (with source) on his blog.   If you have a few minutes, you should check them out!

Here’s a list – check them out – the each include a video:

You can join the AIR on Android beta by going to http://labs.adobe.com/technologies/air2/android/

Even if you don’t yet have an Android devices capable of running AIR, you can use the emulator and still have fun!  I blogged about this recently.

Debating HTML 5 and Flash? Get educated first!

•June 30, 2010 • 10 Comments

You’ve probably heard a lot of noise in the press, blogs, twitter, etc. about HTML 5.  You’ve probably also heard how its new video and animation capabilities combined with other cool HTML 5 features is going to be the death of Flash, right?  As a technical evangelist for Adobe, I obviously know a lot about the capabilities of Flash, but I also have invested a lot of time getting up to speed on HTML 5 so I could fully understand the debate and separate fact from noise.  I’ve been in this field long enough to see several religious technology debates come and go, so I tend to be very pragmatic when it comes to technology shifts.  I’ve also learned over the years to stay very educated on key topics, deal only with facts I can confirm myself, and rely on neither marketing BS nor sensationalism in the press.

I’ve been involved in web development since the early betas of Netscape.  I’ve used Java Servlets, JSPs, ASPs, Perl/CGI, PHP, ColdFusion and other means of dynamically generating web content and have always worked to push browser capabilities to the limit.   From day one I was excited about what web browsers could do, but like many web developers, I was almost instantly frustrated by the limitations and the painfully slow progress of web standards.  It has taken 15 years to reach the capabilities reflected in the HTML 5 spec.  These features should have been in HTML 2 or at least HTML 3!   Many other standards have innovated dramatically faster, so for me personally, HTML 5 is at least 10 years overdue!

The Flash/HTML overlap – Would you replace your <IMG/> tags with Flash?

Flash was added to our toolbox to extend the capabilities of web developers beyond what HTML provided.   It basically has helped developers fill the gap that exists between the desires of our application design and the capabilities of existing web technologies.   The intent of Flash has never been to compete with HTML.  The intent is to help developers realize the goals of our applications.  If HTML and related technologies provided everything we needed, Flash would not exist.

As complementary technologies evolve, there are inevitably overlapping capabilities.  Adobe has never promoted the use of Flash to do things that HTML can do without Flash.  Have you ever heard anyone promoting the use of Flash to display images?  You could replace all of your <IMG> tags with Flash but why would you use a plugin where no plugin is really needed?!   Although Flash would do a great job at displaying your images and even provide some unique features, it’s very unlikely that you need these features so you would be nuts to use Flash!  If Adobe told me to promote this idea, I would move to the Lightroom team! 😉

This is a trivial example of where there is overlap, but because web developers fully understand the requirements and capabilities of displaying images, it’s obvious which technology to use!   The currently debated overlapping features are a bit more complex resulting in confusion for many.

HTML 5 increases the overlap

I remember the first time I saw DHTML used to make cascading menus (2002 I think?), I was impressed!  I could build UI controls that respond to mouse rollover events, dynamically display dropdown menus and all sorts of cool things.  Amazing!  Although this could already be done with Flash, it was nice to see HTML technologies evolve to this level.  (I’ll skip the history lesson about the huge pains we went through to make sure this new coolness worked on multiple browsers.  It was a mess until JQuery and other AJAX frameworks evolved!).

If you look at what HTML 5 is bringing us, you’ll see that the overlap between Flash and HTML 5 is indeed increasing.   HTML 5 introduces animations, drawing capabilities, video, audio,  and many other things that we usually rely on Flash to deliver, so yes, the overlap is obviously larger in many ways.  However, there is a high probability that the overlap is probably not as big as you may think.  Let’s start with the obligatory video debate.

The center of attention in the current debate – Video!

Now I’m going to say something that might surprise you.   If your video needs are met by HTML 5 and your target audience has an HTML 5 capable browser, you SHOULD use the new video tag instead of Flash!   Like I said before, why use a plugin for something that a plugin is not needed for!?  It’s no different than my <IMG/> analogy above.

However, before you draw any conclusions about video… be sure that you completely understand the implications:

1: Does your target audience have an HTML 5 compatible browser capable of viewing your video?

If not, I can assure you that they almost certainly have Flash, therefore, it’s an obvious choice for playback of video on non-HTML5-ready browsers.  Read my prior article, “HTML 5 and Flash – A Reality Check“.  Are you surprised to see that more people use IE6 than Safari?  I was!  Of course there are new devices that support the HTML 5 video tag and some of these new devices do not have Flash support for various reasons (no, I’m not going there), so it basically creates more work for us developers to support 100% of the audience.  Now we find ourselves writing code that handles video playback differently based on the user agent.  It’s reminiscent of the early 2000s and I believe that it’s going to get worse before it gets better because the number of devices, browsers, screen resolutions, OSes, etc. is dramatically larger than ever before.

2: Do your video requirements go beyond simply pointing to a video file with the new video tag?

You would be surprised at how many customers have much more complex requirements.   Here are a few comments made yesterday by John Harding, Software engineer at YouTube on the YouTube blog that illustrates my point:

“It’s important to understand what a site like YouTube needs from the browser in order to provide a good experience for viewers as well as content creators. We need to do more than just point the browser at a video file like the image tag does – there’s a lot more to it than just retrieving and displaying a video. The <video> tag certainly addresses the basic requirements and is making good progress on meeting others, but the <video> tag does not currently meet all the needs of a site like YouTube”

The article goes on to explain multiple technical reasons why Flash will continue to be the video player for YouTube.   You can read the full article at http://apiblog.youtube.com/2010/06/flash-and-html5-tag.html.  Hulu recently made a similar blog post –http://blog.hulu.com/2010/05/13/pardon-our-dust/ that mentions a few other interesting points.   Although HTML 5 provides video playback, many customers find a gap between their requirements and what HTML 5 offers….so once again, Flash fills the gap!

Did you know that there was such a vast difference between the capabilities of HTML 5’s proposed video tag and Flash?  Have you really looked at the complete feature set of Flash video?

Assuming the HTML 5 video format war finally gets resolved (it has a long ways to go), we will indeed see more videos delivered by the browser without the use of Flash, and that is the way it is supposed to be.  However, when you need advanced video capabilities, you will find that Flash once again complements HTML very nicely.

Video is just one aspect of Flash and only one aspect of HTML 5.  I used it as an example of how disconnected people are from the reality of the debate.

As HTML technologies expand, so do the capabilities of Flash

The ever increasing overlap between Flash and HTML 5 is just one part of what’s happening right now.  The other part that is seldom mentioned is the continually increasing capabilities of Flash.   As HTML 5 is slowly realized, Flash continues to innovate at a very fast pace so that it can continue to fill the gap between what HTML technologies offer and what developers want to build.  You should see what’s coming in future versions!  Flash will continue to complement HTML and help developers realize capabilities not possible otherwise.  Can Adobe continue to innovate to fill the gap?  Can Flash evolve fast enough to continue complementing HTML?  You bet.  I’ve seen it!  Eventually, we will be debating HTML 6 vs Flash Player X and we’ll see whole new set of hot topics. Fun times!

Get educated!

Spoken in my stern teacher voice — It is impossible for you to evaluate the future of HTML 5 and Flash unless you are fully educated on both technologies.  I keep meeting developers who have a decent understanding of HTML5 but think Flash is nothing more than simple video and animated ads.  I also meet developers who have a decent understanding of Flash but think HTML 5 is only about adding video, audio and canvas tags to today’s HTML.  In both cases, the person is VERY misinformed and is lacking the required education to make any future-looking statement about either technology.  However, both uneducated groups tend to be very loud!  It reminds me of a political election where people vote based on what they have learned from political ads!  STOP IT!

Whether you are debating technology or politics, it’s an absolute requirement to be equally knowledgeable on all topics involved.

Where to learn more

Hopefully you are now inspired to learn more.  Below are the resources I found while learning about HTML 5.  I’ve also listed some resources about Flash and related technologies.  Go read everything below and let’s have an intelligent and fun discussion about the future.

HTML 5:

  • Google’s http://html5rocks.com – fantastic resource with tons of live demos – my favorite resource for showing off HTML 5
  • Microsoft’s IE 9 test drive home page – includes some very impressive HTML 5 demos – http://ie.microsoft.com/testdrive/ – it’s great to see Microsoft innovating around HTML 5.
  • Apple’s Safari technology demos – some impressive demos of HTML 5, but a bit too “Apple owned” feeling – http://developer.apple.com/safaridemos/ – the original demos only ran in Safari but now also run in Chrome.
  • CanvasDemos – an entire site devoted to the new canvas tag in HTML 5 – some very impressive stuff – http://www.canvasdemos.com/
  • HTML 5 Test site – gives your browser a HTML-readiness score and list the capabilities.  Each listed capability is a hyperlink to the HTML 5 spec – http://html5test.com/
  • HTML 5 Readiness site – shows current status of most modern browsers (anything not listed has no HTML 5 support) – http://html5readiness.com/
  • HTML 5 Demos – a decent set of HTML 5 demos – http://html5demos.com/
  • HTML 5 Video tag browser support matrix – a very up to date article on which browsers support which video formats/codecs, etc. – http://en.wikipedia.org/wiki/HTML5_video
  • Adobe Dreamweaver HTML5 Pack – an amazing set of HTML 5 capabilities you can use today – http://labs.adobe.com/technologies/html5pack/

Adobe Flash Platform:

  • Adobe Flash Platform Home Page – http://www.adobe.com/flashplatform/
  • Flex.org – great starting point for learning about Flex, a developer’s toolkit for creating Flex content.  If you have never looked at Flex, you are missing a big piece of the Flash Platform, especially when it comes to complex application development.  Be sure to check out the showcase (“What’s possible”).  You’ll see that Flex is used to build very complex mission critical apps in the enterprise.  These apps run on the Flash platform.
  • Tour de Flex – a gallery of nearly 500 code samples illustrating everything from simple UI controls to complex data visualizations and real-time data handling – http://flex.org/tour
  • Top Flash Misconceptions by Mike Chambers – addresses some very recent false claims about Flash – http://www.mikechambers.com/blog/tag/flash_myths/
  • What’s new in the latest release of Flash Player 10.1 – a very substantial release – http://labs.adobe.com/technologies/flashplayer10/features.html
  • Adobe AIR home page – a runtime that enables desktop applications built with either Flash, Flex or HTML/JavaScript – http://www.adobe.com/products/air/ – supports Windows, MacOS, Linux, Android (beta) and more on the way.  If you have never looked at AIR, you need to check this out.
  • Flash Media Server home page – http://www.adobe.com/products/flashmediaserver/

Go learn!

Tour de ColdFusion Beta Launched!

•June 24, 2010 • 2 Comments

We have FINALLY launched Tour de ColdFusion! We are still filling in a few gaps and testing, so we consider it a beta, but it’s ready for you to dive in.

Tour de ColdFusion is a desktop application built on Adobe AIR that provides quick access to hundreds of ColdFusion code samples.   Live running samples combined with the source code that you see running is the fastest way to learn!

Over the next few days, we will be adding additional samples.  Tour de ColdFusion will automatically reflect the latest sample database each time you run it so you know that you are seeing the latest, greatest stuff.

Help us make Tour de ColdFusion better by helping us add new samples.   If you have any code samples, techniques, frameworks, etc., that you think would make Tour de ColdFusion an even better learning tool, please contact us at submit@tourdecoldfusion.com.

Please report any issues to bug@tourdecoldfusion.com.

Go to the Tour de ColdFusion Beta home page to download and install.

Tour de Flex 2.0 – AIR and Flex Component and API Explorer Launched!

•June 18, 2010 • 5 Comments

We just posted Tour de Flex 2.0.  If you already have a previous version of Tour de Flex, it should auto-update to 2.0.   This latest version has several bug fixes and now requires AIR 2.0 to support many new AIR 2.0 samples.   Go grab it and check out the new samples in the AIR Applications folder!  There is some great stuff!

THANK YOU to Holly Schinsky (twitter) for building the majority of these new samples in addition to fixing many of the bugs in the Tour de Flex application.

There are now 490 samples in Tour de Flex!

If you don’t already have Tour de Flex, go to http://flex.org/tour.  Tour de Flex is a desktop application for exploring Flex capabilities and resources, including the core Flex components, Adobe AIR, data integration, and a variety of third-party components, effects, skins, and more.