dcsimg

BlazeDS for PHP Developers

Integrate Flex and Java with your PHP application.

If you’ve built a rich Internet applications (RIA) or spent any time surfing the Web, you’ve probably run into Web applications that run in Adobe Flash Player. Flash applications span a wide gamut, from games, to media players, but with the right tools, Flash can also power data-driven software. Adobe Flash Builder combines Adobe Flex and ActionScript 3.0 to connect applications to a service tier, and technologies such as BlazeDS simplify intercommunication, doing much of the work of shuffling data between the Flash application and the service tier for you. Specifically, BlazeDS connects Flex and Adobe AIR applications with services written in Java, using a couple of remoting technologies that offer performance improvements over standard Extensible Markup Language (XML) or SOAP messaging with Web services.

This article provides an overview of how BlazeDS handles messaging from the Flex application to the Java services tier. It also introduces a few techniques that you can use to integrate Flash and Java applications with PHP applications.

Scenarios for PHP, Flex, and BlazeDS

BlazeDS is a communications framework used to talk to Java services from a Flex user interface (UI). You can use PHP for both the UI and for services, so integration of these technologies can occur in a number of different scenarios:

  • Flex to Java to PHP. A Flex UI can call Java services, which in turn can call PHP services or execute PHP scripts to perform particular tasks.
  • Flex to PHP. You can use a Flex UI to call PHP services in addition to or instead of calling Java services. This communication must occur using an alternative to BlazeDS (see Configuring Flex and BlazeDS).
  • PHP to Java. You can use PHP to create a UI for Java services that already exist and perhaps support an existing Flex UI. For example, you could create a PHP UI to support browser environments in which Flash Player isn’t an option.

The sample applications used in this article come with the BlazeDS turnkey download. The samples allow you to try BlazeDS out quickly and with minimal configuration and also showcase different messaging techniques. You can find the source code for the sample applications at samples\WEB-INF\flex-src\flex-src.zip once the turnkey package has been extracted.

BlazeDS Overview

BlazeDS is an open source project from Adobe that facilitates remoting and Web messaging from Flex to Java. You can download the project at no cost from the Adobe Open Source site.

Using the remoting features, you can write ActionScript 3 classes in your Flex applications and use them as arguments to call remote Java classes. Flex and BlazeDS handle the serialization and deserialization of the objects for you, so you don’t have to spend days writing code to form XML messages or spend hours finding and configuring an XML serialization framework to do it for you.

BlazeDS can run as a Web application, distributed in a Web Archive (WAR) file, inside any Java Web application server, such as Apache Tomcat. Once you have the BlazeDS WAR running, all you have to do is make the Java classes that you’ve built accessible to your Web application. BlazeDS supports a number of message types, such as asynchronous messages and publisher and subscriber (pub/sub) messaging.

Running the Turnkey Download

The turnkey download from the BlazeDS’s site provides the WAR, a recent version of Tomcat, the Flex 3 software development kit (SDK), and sample applications. It is designed to launch a Flex application that works with Java as quickly and easily as possible. If you’ve never used Flex or BlazeDS before, it’s perfect for trying the technologies out.

Download the turnkey distribution from the project download site. Extract the .zip file into a directory. Before starting Tomcat, make sure you start the sample database that comes with BlazeDS turnkey:

$ cd BLAZEDS_HOME/sampledb
$ startdb.sh &

The Tomcat distribution is located in the tomcat subdirectory. To start Tomcat, run the following commands:

$ cd BLAZEDS_HOME/tomcat
$ bin/startup.sh

To see what is happening, watch the log file:

$ tail -f BLAZEDS_HOME/tomcat/logs/catalina.out

(Before you can run Tomcat successfully, set the JAVA_HOME variable to the location in which Java is installed. To find it, type locate rt.jar on the command line:

$ locate rt.jar
/usr/lib/jvm/java-6-sun-1.6.0.13/jre/lib/rt.jar
$ export JAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.13/

If locate finds more than one copy of rt.jar, make sure you’re using the copy that matches the version of java found in your path.)

After starting the Tomcat instance that comes with BlazeDS, point your browser to port 8400 on your Web server (for example, http://localhost:8400/). When the Web browser loads the page, you should see links to the sample applications.

Messaging Overview

BlazeDS uses Action Message Format (AMF) to serialize objects as they’re sent from the UI to the services tier and back. Although AMF is an Adobe-designed messaging format, the specifications for it have been published, and Adobe says it’s committed to working with the community. One of the benefits of using AMF is that you can build classes in ActionScript 3.0 that match classes in your Java code, and BlazeDS stitches it all together. Another benefit is that because it’s a published specification, other language implementations aside from Java have surfaced—namely, PHP.

To do messaging with BlazeDS, you configure endpoints in your Web applications to use the MessageBroker, which runs on the server side and receives the message from the client. The MessageBroker runs as a servlet in a Java Web application server, which is similar to a PHP script. It routes the messages to the correct service, depending on the channel and endpoint you use, and passes the messages it receives from the client to the specified remote objects, translating the message for you. When it’s done, it responds and can do so with complex objects, so long as the Java objects on the server side have ActionScript classes mapped to them in the Flex UI.

The MessageBroker supports four different types of channels and endpoints. Endpoints support different message formats and messaging characteristics. The different endpoints look like slightly different URLs in the configuration for the services in the Flex application.

  • AMF. Data are still transported over Hypertext Transfer Protocol (HTTP) from the Flex UI to the special MessageBroker servlet, but in Adobe’s own messaging format. When you configure an endpoint that supports an AMF channel, you can configure features like polling to check the Web server for new messages. Polling has the disadvantage of incurring the time that it takes to open and close connections to the Web server on a repeating basis, but it is supported by HTTP 1.0, because it follows standard HTTP request/response behavior. Using different parameters, you can tune polling to offer a real-time–like experience.
  • HTTP. HTTP is like AMF, except that the message is transported in an XML representation of the AMF format called AMFX. Because the XML is created by serializing objects to XML and deserializing them on the server side, it does not preform as well as the binary messaging. Unless you have to use HTTP, you should use AMF for performance reasons.
  • Streaming AMF. The data are streamed in real time to the server while holding the HTTP connection open (keeping the HTTP connection “alive”). This creates a faster connection because the latency of opening and closing multiple connections is decreased, but has the disadvantage that it is not typical HTTP request/response behavior and therefore is not supported by HTTP 1.0. Use Streaming AMF for real-time services, where performance is key and you can guarantee that the number of clients keeping connetions alive won’t overburden the Web server.
  • Streaming HTTP. The data are streamed like Streaming AMF, except they are in a text-based XML format like HTTP.

You can use the Consumer, Producer, AsyncMessage, and MessageEvent objects to communicate between clients in Flex applications via the MessageBroker. The Producer and Consumer components send and receive messages, respectively, and use classes called AsyncMessage and MessageEvent to do so.

When using asynchronous messaging, a message is sent, and then the rest of the application keeps going: It doesn’t wait for the message response before it continues. This fits in with Flex’s event-driven model, but it takes some getting used to if you’re accustomed to working with more functional programming like PHP. Remember that when you call services or send messages to clients, you handle the result of the message in a callback function—don’t handle the result in the lines of code immediately after the message is sent as if you’ll have a response.

Consider the Collaboration Desktop sample application that comes with BlazeDS turnkey. If you open two copies of the application in different browsers, you’ll see that changes made in one window are reflected in the other window.

Here is an example of part of the application that will send a message:

<mx:Script>
...
private function monthChange() : void
{
  var message : IMessage = new AsyncMessage();
  message.body = {month: timeline.selectedMonth};
  producer.send(message);
}
...
</mx:Script>
...
<mx:Producer id="producer" destination="dashboard" />
...

The details are unimportant for now, suffice to say that the Producer component defined in the application is given the ID producer. The send() method is called in the monthChange() function. Here is an example of part of the application that subscribes to the same destination and displays the message received by the other client:

<mx:Script>
...
private function resultHandler(event : ResultEvent) : void
{
   // snipped...
}
...
</mx:Script>
...
<mx:Consumer id="consumer" destination="dashboard" message="resultHandler(event)" />
...

The Consumer component has the ID consumer and uses the same destination as the Producer component. It defines a function that will be called when a message is received, called resultHandler. Here, the method is defined as accepting a parameter of ResultEvent, which inherits from MessageEvent.

The configuration for the dashboard destination in the Collaboration Desktop application looks like this:

<destination id="dashboard" />

That’s all that is needed for the destination configuration, because it uses the default channel defined in the messaging-config.xml file. These components are covered in more detail in the next sections.

Configuring Flex and BlazeDS

Flex and BlazeDS are both configured by XML configuration files that specify the channels, endpoints, and remote objects used for messaging. The same services configuration files need to exist in both the server application and the Flex client. On the server side, the MessageBroker uses the configuration file to know which channels to listen on. On the client side, the configuration file tells the client which channels and endpoints to use when sending messages. If they don’t match up, the client will be sending messages to locations the MessageBroker won’t be ready for.

Now, you’ve seen a brief overview of how you can configure Flex to send messages between clients. Services are configured in BlazeDS using configuration files that map destinations to channels and channels to endpoints. The endpoints are simply URLs to the specific MessageBroker location.

The configurations are split up in a few different files by convention. The main file is services-config.xml, which maps the channels to endpoints and also assigns other properties, such as polling intervals, to the channel definition.

The services-config.xml file usually includes two other files: messaging-config.xml and remoting-config.xml. You use the messaging-config.xml file to define messaging as discussed above that uses Producer and Consumer components. In contrast, remoting-config.xml maps destinations to remote objects by defining a source property.

Depending on what type of application you’re building, you may have only one or both of these two files. If you’re building a chat application or a similar application where messages are sent between clients via the MessageBroker, you may have only the messaging-config.xml file. If you are building an RIA for managing product inventories, you may have only the remoting-config.xml file. The important thing to remember is that you must define a destination for any type of messaging. By convention, that destination is defined in different files depending on the nature of the messaging.

For an example of a Flex application calling services with RemoteObject components, check out the Inventory Management sample application that comes with the turnkey distribution. The steps for configuring BlazeDS use the Inventory Management configuration as examples.

To configure BlazeDS to call a remote Java object as a service, follow the steps outlined here:

  1. Define a destination in the remoting-config.xml file, and either define a channel or use the default one.
    <default-channels>
      <channel ref="my-amf" />
    </default-channels>
    ...
    <destination id="product">
      <properties>
        <source>flex.samples.product.ProductService</source>
      </properties>
    </destination>
    ...
    
  2. Create a channel definition for the destination in the services-config.xml file.
    ...
    <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
      <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf"
        class="flex.messaging.endpoints.AMFEndpoint"/>
        <properties>
          <polling-enabled>false</polling-enabled>
        </properties>
    </channel-definition>
    ...
    
  3. Define the RemoteObject component in the Flex application, and provide the ID of the destination that you set up in step 1.
    <mx:Script>
    ...
    private function createResult(event : ResultEvent) : void
    {
      // snipped...
    }
    ...
    
    private function removeResult(event : ResultEvent) : void
    {
      // snipped...
    }
    ...
    </mx:Script>
    
    ...
    <mx:RemoteObject id="srv" destination="product">
      <mx:method name="create" result="createResult(event)" />
      <mx:method name="remove" result="removeResult(event)" />
    </mx:RemoteObject>
    ...
    

PHP and Java

If you are integrating PHP services into an existing Flex/BlazeDS/Java application, you have a couple of different options. You can use SOAP/XML remote procedure call (XML-RPC) or the PHP/Java Bridge project if you will call your Java services via BlazeDS, and then call PHP services from your Java services. Another alternative is using the same AMF messaging format that BlazeDS uses with Zend_Amf, an AMF implementation for PHP that allows you to call PHP classes directly from the Flex UI. Finally, you can use Java Message Service (JMS) to send and receive messages from BlazeDS, so any implementation that allows you to place messages in a JMS queue allows you to integrate the technologies.

You can use SOAP to call PHP from Java or Java from PHP by the use of Web services. So long as your version of PHP was compiled with --enable-soap, you can use Java client libraries to call PHP using SOAP and Web services.

One disadvantage of using SOAP is that you need to be more concerned about the message format, depending on which methodology you are using. There are two: contract first and code first.

Contract first means you build the Web Services Description Language (WSDL) contract first, then generate code. It usually offers the best interoperability. However, it requires additional tooling for the code generation, and sometimes the complexity of building out and using the tooling environment is more trouble than it’s worth.

Code first means that you generate WSDL off the code. It’s usually easier to write, but sometimes the tooling doesn’t generate the WSDLs you really want.

A major advantage of using SOAP is that it’s a standard and is fairly well supported in all major languages. You can change the service’s implementation entirely, and the client usually isn’t affected by the change. So, if you call PHP from Java via SOAP, you can change your PHP implementation to another Java implementation, and it would not have to change any of your Java client code.

XML-RPC is—like SOAP—a specification based on XML for messaging, regardless of the implementation. Using XML-RPC has many of the same advantages and disadvantages of using SOAP.

PHP/Java Bridge is a project that provides a way to call PHP from Java and Java from PHP. It provides a WAR that can be installed in a Tomcat instance (the BlazeDS turnkey download works fine for this). After installing the WAR, you can call Java classes from PHP. To call PHP from Java, you use the Java ScriptEngine application programming interface (API) to invoke PHP functions. The ScriptEngine is created in the Java code using a URL that points to a JavaProxy.php script that comes with PHP/Java Bridge.

PHP/Java Bridge uses a special bridge protocol called VM Bridge Protocol to communicate between PHP and Java. The benefits are that it does not use Java Native Interface (JNI) or PHP emulation to do its work, so with PHP and the BlazeDS turnkey installed (and the turnkey requirements), you can run the examples provided at the project Web site.

Zend_Amf is an implementation for AMF messaging in PHP by Zend. Using Zend_Amf, you can use the AMF channels just like you would for communicating with Java services with BlazeDS. At a high level, one way to create a service as an AMF endpoint is to use a class called Zend_Amf_Server, which provides a server implementation similar to the SOAP server. An example of a service called service.php is shown here:

<?php
  $server = new Zend_Amf_Server();
  $server->setClass('MyService');
  $response = $server->handle();
  echo $response;
?>

All you have to do is implement a service in PHP using the Zend_Amf classes and configure an endpoint that points to the URL of your PHP service using the AMF channel. An example of a configuration for the channel definition in services-config.xml is shown here:

...
<channel-definition id="zend-amf" class="mx.messaging.channels.AMFChannel">
  <endpoint uri="http://host.example.com/service.php"
    class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>
...

The destinations are configured in remoting-config.xml to use the zend-amf channel defined here. Everything else in your Flex and ActionScript code can stay the same—just as if you’re using BlazeDS to call Java services. In this manner, you can build your Flex UI to consume both types of services directly.

JMS provides yet another alternative for communicating among Flex, Java, and PHP. Using JMS offers the same advantage of SOAP and XML-RPC, because it provides a way of sending messages using open specifications (see Additional Resources). However, JMS adds to it the benefits of reliable messaging and failover. Messages are placed in a queue, and any component capable of receiving messages in the queue can get them and respond. JMS is often—but not by necessity—used asynchronously.

BlazeDS can send and receive messages directly to and from a JMS queue, so JMS can also be a good choice depending on your implementation. Because JMS is a messaging standard, many implementations are available for services that handle messages. One example of a JMS implementation is Apache ActiveMQApache ActiveMQ.

ActiveMQ can be downloaded and installed as a separate service. The ActiveMQ documentation provides examples for verifying the installation. Once installed, as with any JMS provider, you use the standard javax.jms classes to communicate with the server. This aspect of the JMS specification makes using JMS in Java great, because regardless of the actual implementation that works behind the scenes, the code always stays the same. An example of sending a JMS message from Java using a simple class is shown here:

import javax.jms.*;
import javax.naming.*;

public class MyJavaService
{
  public void sendMessage(String messageText) throws Exception {

    Connection connection = null;
    //This should be configurable... (i.e., System.getProperties());
    String myDestination = "jms/topic/flex/simpletopic";

    try {
      Context jndiContext = new InitialContext();
      ConnectionFactory connectionFactory = (ConnectionFactory)jndiContext.lookup("ConnectionFactory");
      Destination destination = (Destination)jndiContext.lookup(myDestination); 

      connection = connectionFactory.createConnection();
      Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
      MessageProducer producer = session.createProducer(destination);
      TextMessage message = session.createTextMessage();
      message.setText(messageText);
      producer.send(message);
    } finally {
      connection.close();
    }
  }
}

With a generic service written in Java like this one, you can send text messages to a queue that will be picked up by the BlazeDS services and consumed by your Flex UI. Once you have this service in Java, you can either call it using the PHP/Java Bridge or create a Web service in Java that you can call in PHP. Below is an example of using PHP/Java Bridge to call your new class, MyJavaService, from PHP to place a message in a JMS queue:

<?php
  require_once('java/Java.inc');

  $myservice = new java('MyJavaService');
  $myservice->sendMessage('This is my message');
?>

Using this technique, you can write a PHP script that places a message in a JMS queue. Then you can configure BlazeDS to subscribe to that queue. Using a Consumer component just as you would in UI-to-UI communication, your Flex application can receive the message that you placed in the JMS queue. All you have to do in the Flex application (like the Collaboration Dashboard) is configure the destination’s channel to use JMS.

Configuring BlazeDS for JMS

Configuring BlazeDS to use JMS messaging is fairly simple. In fact, it’s more difficult to install and configure a JMS implementation and configure your Web application to work with it than it is to make the relatively small changes necessary to send and receive messages via JMS. To send messages via JMS, first set up an adapter in the messaging-config.xml:

<adapters>
  <adapter-definition id="jms"
    class="flex.messaging.services.messaging.adapters.JMSAdapter"/>
</adapters>

When you’re finished defining the adapter, modify the destination configuration to use the adapter, and set up some properties for the JMS adapter, such as the location of the JMS queues:

<destination id="dashboard">
  <adapter ref="jms"/>
    <properties>
      <jms>
      <!-- snipped... see the BlazeDS developer documentation.
      "myDestination" used in the Java example for placing messages on a queue
      would be configured here.  For example:
      <destination-jndi-name>jms/topic/flex/simpletopic</destination-jndi-name>
      -->
      </jms>
    </properties>
</destination>

Summary

BlazeDS provides the ability to create data-driven RIAs that run in Flash Player and communicate with Java services. The communication is done via AMF, Adobe’s messaging format. To integrate PHP with Java, there are many different solutions for calling PHP from Java and from Java to PHP. Additionally, some technologies are surfacing that allow you to use AMF to communicate directly with PHP, thanks to the open source nature of BlazeDS and documented specification of AMF. Finally, using JMS provides a decoupled implemenation that allows you to use BlazeDS to send JMS messages to queues and process messages using PHP.

Comments on "BlazeDS for PHP Developers"

wagnerbianchi

Very good, great job!!

chad007

Cool! Thanks!

Using blazeds-turnkey-4.0.0.14931, you may need to start the sample db before starting tomcat:

from inside blazeds-turnkey-4.0.0.14931/sampledb, run ./start.sh

You could certainly see your expertise within the paintings you write. The arena hopes for more passionate writers such as you who aren’t afraid to mention how they believe. At all times go after your heart.

Excellent goods from you, man. I’ve understand your stuff prior to and you are just extremely magnificent. I actually like what you have bought right here, really like what you’re stating and the best way through which you say it. You’re making it entertaining and you continue to take care of to stay it sensible. I can not wait to read much more from you. That is actually a wonderful web site.

“Write more, thats all I have to say. Literally, it seems as though you relied on the video to make your point. You obviously know what youre talking about, why waste your intelligence on just posting videos to your blog when you could be giving us something enlightening to read?”

hey there and thank you for your info – I’ve certainly picked up anything
new from on this site. I did however expertise some technical points
by using this website, since I experienced to reload the site a
great deal of times previous to I could possibly buy it to load properly.

I had been wondering if your hosting is OK? Not too I
am complaining, but slow loading instances times will
often affect your placement in google and can damage your quality score
if advertising and marketing with Adwords. Anyway I’m adding this RSS to
my email and can consider much much more of your respective intriguing content.
Ensure you update this again very soon.

my web-site … PatRBackus

I similar to the valuable info you provide in your
articles. I will bookmark your weblog and take a look at again here regularly.
I’m rather certain I’ll be told plenty of new stuff right here!
All the best for the subsequent!

Here is my web blog; KittyICoyt

You’ve made some really good points there.
I looked on the web for extra information regarding the issue and
discovered the majority of people goes together with your thoughts about this website.

my web blog ArlenaRStcyr

Leave a Reply