In a former post on this blog I wrote about messaging from java to flex without using JMS. That can be a good starting point for the current post's topic: http://blog.comtaste.com/2009/03/messaging_from_java_to_flex_wi_1.html.
In that case I was relying on a correct blazeds messaging configuration where a messaging destination called actionscriptMessaging was created.
I can think about several use cases where the number and configuration of messaging destinations cannot be determined at implementation or deploy time: think about social or collaborative applications where users are organized in different groups depending on their interest or a common goal, or a much simpler example, a chat where a user can create a private chat room.
If you want to send messages only to some clients you can use the consumer selector property: http://livedocs.adobe.com/blazeds/1/blazeds_devguide/help.html?content=messaging_6.html or alternatively you can create multiple destinations.
Creating a destination from a J2EE backend (where BlazeDS is deployed) is as simple as writing these lines of code:
MessageBroker broker = MessageBroker.getMessageBroker(null);
service = (MessageService) broker.getService("message-service");
destination = (MessageDestination) service.createDestination("myDest");
if (service.isStarted()) {
destination.start();
}
The service id must be the one specified in messaging-config.xml:
<service id="message-service" class="flex.messaging.services.MessageService">
The message broker is obtained in the same way as the former post, the null parameter is better explained in the class javadocs: http://help.adobe.com/en_US/livecycle/9.0/programLC/javadoc/flex/messaging/MessageBroker.html#getMessageBroker(java.lang.String)
The destination must be started before any client tries to subscribe, otherwise you would get the "No destination configured" error. Here it is the client side subscription:
var c:Consumer = new Consumer();
c.destination = "myDest";
var channelSet:ChannelSet = new ChannelSet();
channelSet.addChannel(new AMFChannel("my-polling-amf", "http://localhost:8080/ContextRoot/messagebroker/amfpolling"));
c.channelSet = channelSet;
c.subscribe();
Of course the destination must match the newly created server side messaging destination; the other peculiarity is the manual setting of the channel used: not having configured a channel server side we can specify the desired channel. That must be among the channels defined in services-config.xml
<channel-definition id="my-polling-amf" class="mx.messaging.channels.AMFChannel">
<endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amfpolling" class="flex.messaging.endpoints.AMFEndpoint"/>
<properties>
<polling-enabled>true</polling-enabled>
<polling-interval-seconds>4</polling-interval-seconds>
</properties>
</channel-definition>
The message sending is the same as specified in the former blog post:
AsyncMessage msg = new AsyncMessage();
msg.setClientId("Java dispatcher");
msg.setTimestamp(new Date().getTime());
// Unique ID
msg.setMessageId(UUIDUtils.createUUID());
msg.setDestination("myDest");
msg.setBody("My message");
//send message to destination
MessageBroker.getMessageBroker(null).routeMessageToService(msg, null);
Note that the message body (in this example a simple string) can be any object mapped in ActionScript with the RemoteClass tag.