Requirements

   
Prerequisite knowledge
Familiarity with Flex and WebORB for .NET is recommended to make the most of this article. Experience configuring Flash Builder project settings is also required.
 
User level
Intermediate
 
Required products
Flash Builder (Download trial)
Additional required other products
producer-test.zip (sample files)
The WebORB for .NET messaging framework has been integrated with Apache NMS and is capable of connecting messaging destinations with NMS destinations. This enables Flex applications to deliver data to and retrieve data from any NMS-compatible messaging provider such as Apache ActiveMQ or Microsoft Messaging Queue (MSMQ) with minimal configuration. WebORB acts as a proxy between the Flex clients and the NMS destination. This article provides an overview of pushing data from a Flex publisher client to a Flex consumer client using an ActiveMQ messaging provider.
 
In the overall system design (see Figure 1), WebORB interacts with the queue through the Apache.NMS interface. The Flex producer client connects with WebORB and begins publishing messages to the queue. The Flex consumer client also connects with WebORB and subscribes to the same queue. When messages are inserted into the queue, WebORB delivers them to the Flex consumer.
 
To learn more about this topic before learning how the sample application works, see the following resources:
 

 
Configuration

WebORB must be configured to connect the Flex clients with ActiveMQ.
 
 
ActiveMQ configuration
In the WebORB bin folder, create an nmsprovider-activemq.config file with the following contents:
 
<configuration> <defaultURI value="activemq:tcp://${activemqhost}:61616?connection.AsyncClose=false"> <userName value="system"/> <passWord value="manager"/> </defaultURI> <maxInactivityDurationURI value="activemq:tcp://${activemqhost}:61616?wireFormat.MaxInactivityDuration=30000&amp;connection.AsyncClose=false"/> <openWireURI value="activemq:tcp://${activemqhost}:61616?connection.AsyncClose=false"> <factoryParams> <param type="string" value="OpenWireTestClient"/> </factoryParams> <userName value="guest"/> <passWord value="guest"/> </openWireURI> </configuration>
 
WebORB configuration
WebORB serves as a gateway between the NMS interfacing queue and the Flex clients. Clients use the weborb.messaging.WeborbProducer API to send messages to the queue, and they use the weborb.messaging.WeborbConsumer API to receive messages from the queue. Alternatively, client applications can use the mx.messaging.Producer and mx.messaging.Consumer classes available in the Flex SDK.
 
WebORB exposes queues as messaging destinations. A queue must be configured as a valid destination in the messaging-config.xml file located in the [WEBORB-INSTALL]/WEB-INF/flex directory. The queue used by the sample application is available at tcp://[YOUR_SERVER_NAME]:61616 and has the name "NMS". To configure the queue as a Flex messaging destination, add the following XML code snippet to messaging-config.xml:
 
<destination id="mmqpush"> <properties> <message-service-handler>Weborb.Messaging.PubSub.NMS.MessagingServiceHandler</message-service-handler> <server> <allow-subtopics>false</allow-subtopics> </server> <nms> <providerURL>activemq:tcp://[YOUR_SERVER_NAME]:61616</providerURL> <destinationName>queue://NMS</destinationName> <messageFactory>Weborb.Messaging.PubSub.NMS.DefaultMessageFactory</messageFactory> </nms> </properties> <channels> <channel ref="my-polling-amf"/> </channels> </destination>
The configuration node above registers the mmqpush messaging destination. The destination is mapped to the same ActiveMQ queue used by the producer and consumer clients. The node includes additional properties for configuring the queue. The destination is exposed over the my-polling-amf channel, which means the Flex clients will communicate with the destination using HTTP polling. Alternatively, the destination could be configured to use the RTMP channel.
 
Apache ActiveMQ also supports topics apart from plain queues; you can use, for example, topic://NMS in the <destinationName> element. For more information, see Apache ActiveMQ - Configuring NMS and Apache ActiveMQ - Examples.
 

 
Developing the Flex consumer and producer client

The sample Flex application for this article acts as both producer and consumer. It performs three major tasks:
 
  • In pingWeborb() it verifies that the server is up and running.
  • In connectAsConsumer() it creates the WeborbConsumer object.
  • In connectAsProducer() it creates the WeborbProducer object.
The first step is to ensure the WebORB server is up and running. The application's creationComplete event invokes onCreationComplete(), which in turn calls pingWebOrb() . Once the server has been pinged, the application calls connectAsConsumer() as well as connectAsProducer() to create the respective WebORB objects. This approach of waking up the WebORB server is better suited for RTMP-based communication, in which you establish a dedicated connection with the server, than the polling method.
 
Here is the relevant code from ProducerTest.mxml:
 
public function onCreationComplete(event:FlexEvent):void { pingWeborb(); } private function pingWeborb():void { var ro:RemoteObject = new RemoteObject("GenericDestination"); ro.source = "Weborb.Management.ManagementService"; ro.endpoint = "http://{server.name}/weborb4/weborb.aspx"; ro.ping.addEventListener(ResultEvent.RESULT, onPingResult); ro.ping.addEventListener(FaultEvent.FAULT, onPingFault); ro.ping(); } private function onPingResult(result:ResultEvent):void { connectAsConsumer("Flex Producer-Consumer Test"); connectAsProducer("Flex Producer-Consumer Test"); } private function onPingFault(fault:FaultEvent):void { Alert.show( "Server reported an error - " + fault.fault.faultDetail); }
To create the WebORB objects, you need to import the WeborbConsumer and WeborbProducer messaging APIs. Furthermore, you have to specify the destination name defined in the messaging-config.xml file ( "mmqpush" ) and wire up the events (such as MessageEvent.MESSAGE , MessageAckEvent.ACKNOWLEDGE , MessageFaultEvent.FAULT ) to appropriate event handlers. Once created, the producer object is used for inserting objects into the queue and the consumer object handles message retrieval.
 
Here is the relevant code from ProducerTest.mxml:
 
import weborb.messaging.WeborbConsumer; import weborb.messaging.WeborbProducer; private function connectAsProducer(subTopic:String):void{ producer = new WeborbProducer(); producer.destination = "mmqpush"; producer.subqueue = subTopic; producer.addEventListener(MessageAckEvent.ACKNOWLEDGE, onMessageAck); producer.addEventListener(MessageFaultEvent.FAULT, onMessageFault); } private function connectAsConsumer(subTopic:String):void{ consumer = new WeborbConsumer(); consumer.destination = "mmqpush"; consumer.subqueue = subTopic; consumer.addEventListener(MessageEvent.MESSAGE, onMessage); consumer.addEventListener(MessageAckEvent.ACKNOWLEDGE, onMessageAck1); consumer.addEventListener(MessageFaultEvent.FAULT, onMessageFault1); consumer.subscribe(); }
This application uses simple String objects as messages, which are handled in onMessage() :
 
private function onMessage(event:MessageEvent):void { trace(event.message.body); consumerData += event.message.body + "\n"; }
If you wish to use complex data types, you may need to cast the event.messages.body property accordingly.
 
In sendMessage() , String objects are pushed asynchronously into the queue using the WeborbProducer send() method:
 
private function sendMessage(mesgForConsumer : String) : void { if(mesgForConsumer != "" && mesgForConsumer.length > 0) { producer.send(new AsyncMessage(mesgForConsumer)); producerData += mesgForConsumer + "\n"; msgBox.text = ""; } }
The full source code is available in the ProducerTest.zip file.
 

 
Running the application

Follow the steps below to run the sample application:
 
  1. Download and start the ActiveMQ messaging provider application (activemq.bat).
Note: When you start ActiveMQ, note the "Listening for connections" pathname, which you'll need in the WebORB configuration.
 
  1. Download and install WebORB. Make the required changes in the flex\messaging-config.xml file as discussed in the WebORB configuration section above.
  2. After downloading the Apache.NMS and Apache.NMS.ActiveMQ DLLs, deploy them in the WebORB bin folder. Also, add the nmsprovider-activemq.config file as described in the ActiveMQ configuration section. WebORB will restart automatically.
  3. Open a command prompt window and change the directory to the WebORB product installation folder (for example, c:\Program Files\WebORB for .NET\4.3.0.1\).
  4. Run weborbee.exe. This is the WebORB Enterprise Edition standalone server. It runs as an independent process; without a license key, it will run only for 30 minutes at a time.
  5. Download the Flex project, and compile the Flex client. Make sure you add the following as an additional compiler argument:
-services "pathname_in_your_machine_to_the_WebORB_directory/WEB-INF/flex/weborb-services-config.xml"
Also, add WebORB.swc to the Flex project Build Path library (weborb.swc is located in [WEBORB HOME]\weborbassets\wdm).
 
  1. Run the client. Type a message in the textbox and click Send. The message will be displayed in the Producer Component text area as it is being sent to ActiveMQ. Once the message is retrieved, it will be visible within the Consumer Component text area.

 
Where to go from here

Now that you have the basic application working, you may want to try different messaging providers, such as MSMQ. For MSMQ, you will have to create a nmsprovider-msmq.config file in WebORB's bin folder with the following content:
 
<configuration> <provider assembly="Apache.NMS.MSMQ.dll" classFactory="Apache.NMS.MSMQ.ConnectionFactory"/> </configuration>
Also, you will have to copy Apache.NMS.MSMQ.dll to the bin folder. Because Apache.NMS.MSMQ.dll is available only in source file format and you will have to check out the project from the repository, compile it, and generate the DLL yourself:
 
Version 1.2.x is compatible with Apache.NMS.dll v1.3.0, which is being referenced by WebORB.dll at present. Note that, unlike ActiveMQ, MSMQ does not support topics.