Messaging destinations is the central concept in publish/subscribe messaging supported by WebORB. The feature is available for Flex, AIR, Javascript, native Java/Android, and .NET clients. A program can be in the role of producer or consumer (or both). Producers publish messages into a destination and consumers subscribe to receive published messages. Typically messaging destinations are registered in a configuration file (WEB-INF/flex/messaging-config.xml), however, WebORB also supports destinations created at run-time – thus called dynamic messaging destinations. The dynamic nature of the destinations can add a lot of flexibility to applications relying on publish/subscribe messaging. For instance, one can easily create a short-lived messaging destination for quick message exchange or some private messaging. The example below demonstrates Java code registering a dynamic destination using the WebORB for Java API:
package demo.messaging.destination;<br /><br />
import weborb.ORBConstants;<br /><br />
import weborb.config.FlexMessagingServiceConfig;<br /><br />
import weborb.config.ORBConfig;<br /><br />
import weborb.config.ORBServerConfig;<br /><br />
import weborb.management.messaging.FlexMessagingDestination;<br /><br />
import weborb.messaging.v3.MessagingDestination;<br /><br />
import weborb.messaging.v3.MessagingServiceHandler;<br /><br />
import weborb.v3types.core.DataServices;</p><br />
<p>import java.util.Hashtable;</p><br />
<p>public class DestinationFactory<br /><br />
{<br /><br />
public <div style="display: none"><a href='http://ccialisonlinee.com' title='cialis online without prescription'>cialis online without prescription</a></div> String createMessagingDestination( String name ) throws Exception<br /><br />
{<br /><br />
// create destination object. This is as basic as it gets, constructor with the destination name<br /><br />
MessagingDestination destination = new MessagingDestination( name );</p><br />
<p> // setup the most basic properties - the name of the class handling<br /><br />
// subscriptions and publications and a class where the messages are stored<br /><br />
// until they are retrieved by the consumers.<br /><br />
Hashtable properties = new Hashtable();<br /><br />
properties.put( ORBConstants.MESSAGE_STORAGE_POLICY, &quot;weborb.messaging.v3.MemoryStoragePolicy&quot; );<br /><br />
properties.put( ORBConstants.MESSAGE_SERVICE_HANDLER, &quot;weborb.messaging.v3.MessagingServiceHandler&quot; );</p><br />
<p> // register properties<br /><br />
destination.setProperties( properties );</p><br />
<p> // initialize handler from the properties<br /><br />
destination.setConfigServiceHandler();</p><br />
<p> // register the destination<br /><br />
DataServices dataServices = ORBConfig.getORBConfig().getDataServices();<br /><br />
dataServices.getDestinationManager().addDestination( name, destination );</p><br />
<p> // REGISTERING DESTINATION SO IT IS VISIBLE IN THE MANAGEMENT CONSOLE<br /><br />
// The following two lines are needed if you would like the destination<br /><br />
// to appear in the management console, therefore the code below is optional</p><br />
<p> // set the channel name, so the console knows how to connect to the destination<br /><br />
// in the &quot;Test Drive&quot; mode.<br /><br />
destination.setChannelName( &quot;my-polling-amf&quot; );<br /><br />
FlexMessagingServiceConfig serviceConfig = ORBServerConfig.getFlexMessagingServiceConfig();<br /><br />
serviceConfig.addFlexMessagingDestination( FlexMessagingDestination.getDestinationScope( destination ) );<br /><br />
return name;<br /><br />
}<br /><br />
}<br /><br />
To further demonstrate how dynamic destinations can be used with the Flex client, see the following Flex application code. The application’s workflow consists of the following steps:
- User enters a name for a dynamic destination to create and pressed the Create Destination button.
- Flex client invokes the createMessagingDestination Java method shown above.
- When the remote method invocation returns a result, the Flex client constructs a Producer and a Consumer objects. The consumer is subscribed to the newly created destination.
- When the user enters text and clicks the Send Message button, the Flex client uses the Producer object to publish the message into the destination.
- The consumer object receives the message from the destination and displays it in the text area.
<br /><br />
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br /><br />
&lt;s:Application xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot;<br /><br />
xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot;<br /><br />
xmlns:mx=&quot;library://ns.adobe.com/flex/mx&quot;<br /><br />
width=&quot;100%&quot; height=&quot;100%&quot; creationComplete=&quot;init()&quot;&gt;<br /><br />
&lt;s:layout&gt;<br /><br />
&lt;s:FormLayout/&gt;<br /><br />
&lt;/s:layout&gt;<br /><br />
&lt;s:states&gt;<br /><br />
&lt;s:State name=&quot;InitialState&quot;/&gt;<br /><br />
&lt;s:State name=&quot;DestinationCreated&quot;/&gt;<br /><br />
&lt;/s:states&gt;<br /><br />
&lt;fx:Declarations&gt;<br /><br />
&lt;!-- Place non-visual elements (e.g., services, value objects) here --&gt;<br /><br />
&lt;/fx:Declarations&gt;<br /><br />
&lt;fx:Script&gt;<br /><br />
&lt;![CDATA[<br /><br />
import mx.controls.Alert;<br /><br />
import mx.messaging.ChannelSet;<br /><br />
import mx.messaging.Consumer;<br /><br />
import mx.messaging.Producer;<br /><br />
import mx.messaging.channels.AMFChannel;<br /><br />
import mx.messaging.events.MessageEvent;<br /><br />
import mx.messaging.messages.AsyncMessage;<br /><br />
import mx.rpc.events.FaultEvent;<br /><br />
import mx.rpc.events.ResultEvent;<br /><br />
import mx.rpc.remoting.RemoteObject;<br /><br />
import weborb.messaging.WeborbMessagingChannel;</p><br />
<p> private var remoteService:RemoteObject;<br /><br />
private var consumer:Consumer;<br /><br />
private var producer:Producer;</p><br />
<p> public function init():void<br /><br />
{<br /><br />
remoteService = new RemoteObject( &quot;GenericDestination&quot; );<br /><br />
remoteService.source = &quot;demo.messaging.destination.DestinationFactory&quot;;<br /><br />
remoteService.createMessagingDestination.addEventListener( ResultEvent.RESULT, destinationCreated );<br /><br />
remoteService.createMessagingDestination.addEventListener( FaultEvent.FAULT, gotError );<br /><br />
}</p><br />
<p> private function destinationCreated( evt:ResultEvent ):void<br /><br />
{<br /><br />
currentState = &quot;DestinationCreated&quot;;</p><br />
<p> consumer = new Consumer();<br /><br />
consumer.destination = evt.result as String;<br /><br />
//var channel:AMFChannel = new AMFChannel( &quot;custom-amf-channel&quot;, &quot;weborb.wo&quot; );<br /><br />
var channel:WeborbMessagingChannel = new WeborbMessagingChannel( &quot;custom-rtmp-channel&quot;, &quot;rtmp://localhost/root&quot; );<br /><br />
var channelSet:ChannelSet = new ChannelSet();<br /><br />
channelSet.addChannel( channel );<br /><br />
consumer.channelSet = channelSet;<br /><br />
consumer.addEventListener( MessageEvent.MESSAGE, gotMessage );<br /><br />
consumer.subscribe();</p><br />
<p> producer = new Producer();<br /><br />
producer.destination = evt.result as String;<br /><br />
producer.channelSet = channelSet;<br /><br />
}</p><br />
<p> private function gotError( evt:FaultEvent ):void<br /><br />
{<br /><br />
Alert.show( &quot;Server reported an error: &quot; + evt.fault.faultDetail );<br /><br />
}</p><br />
<p> private function createDestination():void<br /><br />
{<br /><br />
remoteService.createMessagingDestination( destinationName.text );<br /><br />
}</p><br />
<p> private function sendMessage():void<br /><br />
{<br /><br />
var asyncMessage:AsyncMessage = new AsyncMessage( messageText.text );<br /><br />
producer.send( asyncMessage );<br /><br />
}</p><br />
<p> private function gotMessage( evt:MessageEvent ):void<br /><br />
{<br /><br />
log.text = evt.message.body.toString() + &quot;\n&quot; + log.text;<br /><br />
}<br /><br />
]]&gt;<br /><br />
&lt;/fx:Script&gt;<br /><br />
&lt;s:HGroup width=&quot;100%&quot; paddingBottom=&quot;2&quot; paddingTop=&quot;2&quot; verticalAlign=&quot;middle&quot;&gt;<br /><br />
&lt;s:Label width=&quot;150&quot; text=&quot;Destination Name:&quot;/&gt;<br /><br />
&lt;s:TextInput id=&quot;destinationName&quot;/&gt;<br /><br />
&lt;s:Button label=&quot;Create Destination&quot; click=&quot;createDestination()&quot;/&gt;<br /><br />
&lt;/s:HGroup&gt;<br /><br />
&lt;s:HGroup width=&quot;100%&quot; paddingBottom=&quot;2&quot; paddingTop=&quot;2&quot; verticalAlign=&quot;middle&quot;&gt;<br /><br />
&lt;s:Label width=&quot;150&quot; text=&quot;Message:&quot;/&gt;<br /><br />
&lt;s:TextInput id=&quot;messageText&quot;/&gt;<br /><br />
&lt;s:Button label=&quot;Send&quot; click=&quot;sendMessage()&quot; enabled=&quot;false&quot;<br /><br />
enabled.DestinationCreated=&quot;true&quot;/&gt;<br /><br />
&lt;/s:HGroup&gt;<br /><br />
&lt;s:HGroup width=&quot;100%&quot; height=&quot;200&quot;&gt;<br /><br />
&lt;s:TextArea id=&quot;log&quot; width=&quot;413&quot; height=&quot;100%&quot;/&gt;<br /><br />
&lt;/s:HGroup&gt;<br /><br />
&lt;/s:Application&gt;<br /><br />
Since the client code references the weborb.messaging.WeborbMessagingChannel class (needed only if the client-server publish/subscribe communication should be done via RTMP), the application must reference weborb.swc in the Flash Build Path of the project. The library is available at:
WebORB for Java – [WEBOBR INSTALL DIR]/webapp/weborbassets/wdm
WebORB for .NET – [WEBOBR INSTALL DIR]/weborbassets/wdm
Complete Flex project with the code shown above can be downloaded from:
http://examples.themidnightcoders.com/blog/dynamicdestinations/DynamicDestinationDemo.zip
Compiled Java code can be downloaded from (the file should be deployed into WEB-INF/lib):
http://examples.themidnightcoders.com/blog/dynamicdestinations/dynamicdestinations.jar
For more information about the Dynamic Destination API, see the corresponding section in the WebORB Documentation.
