Skip to content

Connecting Flash and Javascript via BlazeDS and DWR – 1/2

2008 October 3
by Sven Busse

Juten Tach,
i am currently involved in a new website project, which will use mostly html with some flash modules here and there, exactly how it should be. We will have a lot of going on in the backend and need a good architecture for having client-server-communication. Since we will not only have flash modules talk to the backend, but also a lot of html-javascript modules, that need access, too, the question arose, what kind of interface to choose, which would be lightweight and fast, but still easy to use. In addition we didn’t want to develop things twice on the backend for both client technologies.

The first thing, that comes to mind, would be some kind of webservices, or xml. Problem here is, webservices are usually bloated and carry huge amounts of meta-stuff for transporting only some little data. XML on the other hand requires you to develop parsers on all sides, backend, flash and javascript.

So we figured, it might be a good idea to look into remoting, finally (sigh). The good news is, everything in this domain is opensource now. For example on the Flash side, we have BlazeDS now, being officially developed by Adobe. On the HTML/Javascript side, we found the DWR framework to be light and easy to use.
Both technologies work in the way, that they make Java objects on the backend accessible to the client, either Flash or Javascript. And they do it without the need of those Java classes to know anything about BlazeDS or DWR respectively, which is, why i think, this solution is wonderfull, because you develop your interface on the java side only once and let multiple connectors like DWR and BlazeDS make the same Java class accessible to different client technologies like Flash and HTML/Javascript.

OK, enough theory, now i wanted to test, if our idea works in practice.

BlazeDS backend
Since i have never done anything with remoting before, it took me a while to figure out, how this stuff works. Fortunately, setting up a tomcat with BlazeDS is fairly easy. You simply create a new web application folder and put all the BlazeDS .jar files in the lib folder. Once this is done, my sample application folder looked like this:

web-application-folder.gif
OK. The documentation for BlazeDS tells us, that tomcat should have 512MByte of reserved RAM, so i configured that in the catalina.bat of tomcat (the important line there then looks like this: `set JAVA_OPTS=%JAVA_OPTS% -Xmx512m -Djava.util…`). Now i wrote one of the easiest server applications, you could imagine, just for testing purposes. It goes like this:

package de.ghost23.blaze_dwr_test;
public class Calculator {
   public long multiply(long a, long b) {
      return a*b;
   }
}

Awesome, right? I didn’t test it, but let’s assume, it works. The cool thing again is, as you can see, this class is totally independet of anything like BlazeDS or DWR. I guess the guys, that have worked with remoting before, cannot understand my enthusiasm, but i find it just nice. I simply put this class along with it’s package folders into the “classes” directory of the WEB-INF directory.

Now once the server application was ready i had to configure it for BlazeDS to make it available for Flash. There are several config files lying around all over the place in the web application folder. The first one is the web.xml file, lying directly in the WEB-INF folder in my application folder. Here you have to actually introduce BlazeDS to tomcat. First you add the MessageServlet:

<servlet>
   <servlet-name>MessageBrokerServlet</servlet-name>
   <display-name>MessageBrokerServlet</display-name>
   <servlet-class>
      flex.messaging.MessageBrokerServlet
   </servlet-class>
   <init-param>
      <param-name>services.configuration.file</param-name>
      <param-value>/WEB-INF/flex/services-config.xml</param-value>
   </init-param>
   <load-on-startup>1</load-on-startup>
</servlet>

Then you add a mapping, that maps calls to a specific url pattern to this service:

<servlet-mapping>
   <servlet-name>MessageBrokerServlet</servlet-name>
   <url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>

That’s it for web.xml file. Now you could already see, there is services-config.xml file referenced above. BlazeDS uses it to configure itself. You can grab one from the sample web applications, that come with BlazeDS. I then deleted the lines, where the “proxy-config.xml” and the “messaging-config.xml” are referenced, because i don’t need these services. The service, that i was interested in, is configured in the “remoting-config.xml”. This is, where things get interesting. Here you declare the class, that you want to be accessible. Therefore i added these lines:

<destination id="calculate">
   <properties>
      <source>de.ghost23.blaze_dwr_test.Calculator</source>
   </properties>
</destination>

Very simple, i don’t think i have to explain it, hu? Also, you have to define a “channel”, over which the communication will take place. The default channel was named: “my-amf”. I changed it to “java-amf”, because, uhm, i wanted to. Now, that’s it. The backend side is ready. Now up for the client.

BlazeDS client
I could have finished this in 5 minutes. All the examples you find in the documentation for BlazeDS use Flex with MXML for connecting to a BlazeDS server. Grrrr, I DON’T WANT FLEX !!! So, that meant, i had to scan through the net for finding ways of doing this without all this MXML stuff. You cannot live completely without stuff from the flex framework, but you can drastically reduce the amount of flex classes amd you can use them in a pure Actionscript project. There are two resources i found, here and here, which helped me finding two alternative solutions, one resulting in a 82 KiloByte .swf file and the other resulting in a 17 KiloByte .swf file. Guess, in which one Flex classes were more involved :) . I will only describe the smaller solution here, at the end of this post i have posted the complete project, which has both versions.

But first things first. First of all you have to link some necessary libraries in order to make all this work. You find all of these in the Flex SDK in the folders (depending on the location of your flex sdk): `C:\flex_sdk_3\frameworks\libs`. Simply link all the .swc files in your project, except for the AIR .swc (unless you want to make a AIR project). Also, for some reason you also have to link the locales, which can be found here: `C:\flex_sdk_3\frameworks\locale\en_US`. Now your ready to start developing your client application. The next hurdle is right there: Since i was not using the flex framework i had to make sure, that i captured the necessary message classes for en-/ decoding. You do this via the `registerClassAlias()` method. Then i could finally put the code down for using the remoting services. The resulting class looked like this:

package {
   import flash.display.Sprite;
   import flash.net.NetConnection;
   import flash.net.Responder;
   import flash.net.registerClassAlias;
   import mx.messaging.messages.*;
 
   public class sbusse_blazeds extends Sprite {
      private var netConnection:NetConnection;
      public function sbusse_blazeds() {
 
         registerClassAlias(
            "flex.messaging.messages.RemotingMessage",
            RemotingMessage
         );
 
         registerClassAlias(
            "flex.messaging.messages.AcknowledgeMessage",
            AcknowledgeMessage
         );
 
         registerClassAlias(
            "flex.messaging.messages.ErrorMessage",
            ErrorMessage
         );
 
         netConnection = new NetConnection();
         netConnection.connect(
            "http://localhost:8080/sbusse/messagebroker/amf"
         );
 
         var methodArguments:Array = new Array();
         methodArguments.push(4);
         methodArguments.push(5);
 
         var remotingMsg:RemotingMessage = new RemotingMessage();
         remotingMsg.operation = "multiply";
         remotingMsg.body = methodArguments;
         remotingMsg.destination = "calculate";
         remotingMsg.headers = {DSEndpoint: "java-amf"};
 
         var respnd:Responder = new Responder(onResult, onFault);
         netConnection.call(null, respnd, remotingMsg);
      }
 
      private function onResult(e:AcknowledgeMessage):void {
         trace("RPC Ok");
         trace(e.body);
      }
 
      private function onFault(e:ErrorMessage):void {
         trace("RPC Fail");
         trace(e.faultString);
      }
   }
}

Note, if you want to pass or receive additional objects from to or from the server, you might have to call `registerClassAlias()` for them to. Otherwise the objects cannot be casted to the correct class in the response. Now, that’ it for the client. Now i have put the flash client in my client folder within my application folder, fired up tomcat, loaded the flash client via `localhost:8080/sbusse/client/flash.swf` and tadaa: 4 multiplied with 5 equals 20! Who would’ve guessed?
In the next post i will add the DWR version for HTML/Javascript.
Download of the sourcecode for the whole Test here.

3 Responses leave one →
  1. Thomas Segismont permalink
    December 5, 2008

    Hi
    I’m really interested in your DWR version.
    I am currently trying to migrate an ExtJS / DWR project to Adobe AIR / ExtJS / DWR
    I got stuck when trying to include dynamically DWR scripts. Then, I got a copy of generated DWR to my workspace but it seems Ajax Requests cannot reach the server.
    Thanks by advance

  2. April 8, 2009

    with the rpc.swc from Flex Build 3, the call could just fail quietly.

  3. fid permalink
    July 3, 2009

    Hi:
    Thank you very much for your article.

Leave a Reply

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS

*