14 March 2011
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.
Intermediate
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>
<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&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 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.
The sample Flex application for this article acts as both producer and consumer. It performs three major tasks:
pingWeborb() it verifies that the server is up and running.connectAsConsumer() it creates the WeborbConsumer object.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.
Follow the steps below to run the sample application:
Note: When you start ActiveMQ, note the "Listening for connections" pathname, which you'll need in the WebORB configuration.
-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).
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.
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.