Showing posts with label flex. Show all posts
Showing posts with label flex. Show all posts

Sunday, February 17, 2008

Working With BlazeDS Beta 1

Last week we successfully ported an AIR application from amfphp to BlazeDS. The code for this application was almost completely generated by a new generator we're working on (coming soon!). With the announcement of BlazeDS, we kinda shelved our php generator and redirected our efforts in doing the same thing for BlazeDS. In the process, we put together our own version of the blazeds.war file that ships with BlazeDS beta 1, which we use as the starting point for all our BlazeDS projects. Here's a list of the changes we've made:

  • Modified the context.xml found in the META-INF folder - the packaged one was producing Valve Errors
  • Added the missing my-streaming-amf channel to services-config.xml, which I found in the BlazeDS samples war's config file
  • Incorporated the latest Flex 3 Compiler Module files to allow server-side compilation of mxml files
  • Created a very simple java class and a corresponding destination which will verify Blaze backend functionality
  • Created a very simple Flex application that calls the above java class function test(string)
  • Added 2 jars to WEB-INF, one is crazedTemplate.jar, which our new codegenerator (coming soon) uses, the other is sharpertools.jar, which the jar requires.
You can choose to go ahead and just use the application as is. It's only been tested on Tomcat / Win / OSX 10.5.2. If you don't intend on using our generator (coming soon!) to generate your java and AS3 Classes then you can go ahead and delete the 2 jars mentioned above. I really like this separation of compiler and essentially what was FDS. When FDS was originally released, it did both runtime compiles as well as Remoting, Messaging, Proxy and Managed Data Services. In our case, we never deployed anything that required runtime compilation AND furthermore, with each subsequent Flex release (2.01, Hotfix 1, 2 and 3), converting FDS projects that were set to compile on the server wasn't trivial. So we stopped using it. If I was super Java savvy I might have been able to figure out what parts I could yank out of my FDS application, but generally it seemed better to just leave it alone.

Now, with Blaze and the compiler war being separate, I've gone through the web.xml in this project and put comments to show which pieces are required by the compiler module and which pieces are required by Blaze. To get this back to being a pure Blaze non-Flex 3 Compiler Module, you'd just need to remove the appropriately marked sections from the web.xml and then remove all folders and files from WEB-INF/flex with the exception of:
  • services-config.xml
  • remoting-config.xml
  • proxy-config.xml
  • messaging-config.xml
Some of our clients have asked what the differences exactly are between BlazeDS and LCDS (prev. known as FDS). If you do enough research on the web, you can find several answers. From what I've seen, here's some differences I've found so far:
  • BlazeDS does not support the RTMP Channel typically used by LCDS for data push (RTMP typically means firewall port challenges all around anyway!)
  • BlazeDS does support AMF Streaming which offers data push like RTMP, however not nearly as scalable (100's vs 10000's of concurrent users)
  • BlazeDS does support proxy so you can bypass the all too familiar sandbox issues when accessing remote data where no crossdomain.xml is present
  • BlazeDS does not come packaged with the Compiler Module
  • BlazeDS does not have managed dataservices. This means that you don't need the fds.swc (DataService & [Managed]) in your flex projects.. you will use either Consumer, Producer or RemoteObject Classes
  • BlazeDS does support AMF3, RemoteClasses & Messaging with a "lite" version of push via amf streaming
To download the blazeBlank application click here. (as new builds of Flex 3 and BlazeDS are released I'll try to keep this application updated). This application currently uses Flex 3 Beta 3 and BlazeDS Beta 1. Be sure to visit the url /{context}/TestApp/Main.mxml to ensure that the application is working properly. (i.e. http://localhost:8600/blazeBlank/TestApp/Main.mxml)

Tuesday, April 10, 2007

A closer Look at IFrames and ExternalInterface in Flex

Well I've been super busy as usual, working on some pretty cool stuff, still managing to only put food on the table but also sticking to my guns and doing only Flex projects. Of course, my blogging has suffered dearly.

In one of my current projects, I am faced with the challenge of somehow embedding IFrames inside my flex app, however without having any control over the html wrapper that my Flex app will sit in. Sure I could 'advise' users on adding the appropriate javascript functions and the hidden div element at the bottom of the body, as we've seen in other Flex Iframe examples out there. But I figured there had to be a way to do this without needing to rely on this external dependency.

As it turns out I can do inline Javascript function calls within my ExternalInterface.call, an example of this would be:

ExternalInterface.call("function(){return window.location.href;}");
which is a simple little function to quickly get the address of the current page. Another handy example is this one:

ExternalInterface.call("function(){document.location.href=document.location;}");
This is a quick way for a user to 'logout' of the flex application, it simply reloads the web page. So as you can see, we can do a great deal without ever needing to touch the html wrapper. So why not do the same thing with Iframe support? Here's what I came up with:
ExternalInterface.call("function(){" +
"var tempIFrame=document.createElement('div');" +
"tempIFrame.setAttribute('id','vyFrame');" +
"tempIFrame.style.position='absolute';" +
"document.body.appendChild(tempIFrame);" +
"tempIFrame.style.backgroundColor='transparent';" +
"tempIFrame.style.border=0;" +
"tempIFrame.style.visibility='hidden';}");
I am going to try and create a div element in memory and append it to the DOM. It's best to run this code during the application preinitialize() event. However, before I move on to explain the rest I just want to mention that I did run into some issues here with IE6. As you'll notice I appendChild and then I set the styles. Turns out that if I manipulate a new element too much prior to adding it to the DOM, it just gets all flaky and will not work. Believe me, this was not an easy bug to track down!

Now, we need to change the remaining externalInterface calls as well... things like move, hide, show and source. Building on the example at deitte.com that first got me started ages ago, I changed all the calls as they are found in his IFrame.mxml component:

ExternalInterface.call("moveIFrame",globalPt.x ,
globalPt.y, this.width, this.height);
Becomes:
ExternalInterface.call("function(){" +
"var frameRef=document.getElementById('vyFrame');" +
"frameRef.style.left=" + globalPt.x + ";"+
"frameRef.style.top=" + globalPt.y + ";" +
"var iFrameRef=document.getElementById('vyIFrame');" +
"iFrameRef.width=" + this.width + ";" +
"iFrameRef.height=" + this.height + ";}");
ExternalInterface.call("loadIFrame", source);
Becomes:
ExternalInterface.call("function(){vyFrame.innerHTML='" +
"<iframe id=\"vyIFrame\" src=\"" + source +
"\" frameborder=\"0\"></iframe>';}");
ExternalInterface.call("showIFrame");
Becomes:
ExternalInterface.call("function(){" +
"document.getElementById('vyFrame').style.visibility='visible';}");
ExternalInterface.call("hideIFrame");
Becomes:
ExternalInterface.call("function(){" +
"document.getElementById('vyFrame').style.visibility='hidden';}");

After a bit of testing I did manage to get this to work, sort of. I ended up spending some time playing with the compiler options in Flexbuilder. I found that if I turned off history management, my Iframes wouldn't appear. However removing the script reference to history.js seemed to have no real effect. For those of you that are not Flash-savvy :) it turned out that the only things to really watch out for, and again I am at the mercy of the users who embed my flex app into their html pages, is that the AC_FL_RunContent() has a final parameter setting of "wmode", "opaque" and the object embed tag also contains wmode="opaque". If this setting is not there or set incorrectly the Iframe will appear behind your flash player.