Online/Offline Application Take Two (Part 3) - Bringing in CFML
In my earlier posts (way back in April 2010) I outlined how our Air client would work by using the HTMLHost with a couple special workarounds. Since then I've been pulled in many different directions, and its suffice to say that I am back on this project. In this post I will focus on setting up the CFML environment inside of the Flex/Air environment. If you've read my previous posts (Part 1 and Part 2), you'll see what we are trying to accomplish. In Part 2 I described how to setup the Flex/Air application to be much like a browser, albeit a very limited one. This worked well enough (many pitfalls which I will document in a future post), so the next step was to get it to render my CFML app.
Bringing in CFML...
As you know, CFML applications require a CFML engine to process the code and return HTML (or xml, json, etc...) that the "browser" can render. You also know that Adobe CF aint cheap if you are considering installing it on client PCs. There is a free developer version, however this usage may violate the licensing if you develop a commercial app that deploys or relies on it, and it does things like watermarking PDFs which is not desireable. It also requires an installation and on Windows runs as a service, which we cannot interact with directly using Air's nativeProcess methods. This will not do for most folks.
Fortunately there's Railo. Railo 3.1 and later is open source and FREE. Best yet it comes in an "Express" version that requires no installation at all. You can download the zip file from http://www.getrailo.org and execute the start.bat (Windows) and you have a living, breathing CFML engine. Also the very nature of Railo is very conducive to client installs as it allows you to set per context locales, datasources, etc... Brilliant!
Now how do we leverage that in Air? I did so by using a simple class I named RailoService.as. This class has the functions to start and stop Railo as the Air browser loads/unloads. Before I show how that is done, here's how I organized the Railo files in my project:
- I downloaded the Railo Express with Jetty from http://www.getrailo.org/index.cfm/download/ (making sure to get the one With JRE)
- Created a folder in my Air project called "src/www/railo/" and extracted the Railo Express archive into that directory.
- I edited the start.ini file in the src/www/railo/ folder by commenting out all of the config files in the # Configuration files section (at the end of the file). For single instance applications this is not necessary, but for my case I need multiple instances so I pass those in when I start Railo within RailoService.as
public function start():void{private function execute(processArgs:Vector.<String>):void{To stop railo, I use the WindowedApplication's close event to fire RailoService.stop(), which mimics the stop.bat:
public function stop():void{
browser.location = "http://www.myapplication.com";
to
browser.location = "http://localhost:8888";
Then copy your CFML app into the webroot folder. If you run the application the browser should render your home page (that is if you don't require a database... I'll cover that in Part 4).
Closing notes:
It is fair to note that once your Air app is running, one could simply pop open any browser and navigate to http://localhost:8888 and gain access to the application. So if you are looking at using Air as a way of preventing users from using a web browser (which has view source, a back button, etc...) you'll need to tweak your CFML code to only run if the cgi user agent is the Air browser. Another noteworthy item along the same lines is that in a regular browser you can also access the Railo admin, by default it would be located at http://localhost:8888/railo-context/admin/server.cfm (or web.cfm for context specific admin). This is handy, but in my app I configure all my Railo settings up using a remote object call to a webservice (hosted on the client) that performs a series of calls to setup the database, locale, etc...