Accessibility

Table of Contents

Introduction to the Flex Message Service

A simple Flex messaging application

Before delving into the design of the Flex messaging infrastructure, create a very simple application to get some messages flowing through the system. Figure 2 shows a very simple chat application that includes just enough functionality to create simple text messages and send them to all other instances of the same application running on any number of client hosts.

A simple chat application based on Flex

Figure 2. A simple chat application based on Flex

The application has a text box for message input and a text area to display messages as they arrive. A button on the panel allows the output to be cleared. Obviously, this application is bare bones, with no logins or the like, but it illustrates the publish-subscribe message flow in a client application.

Here is the code listing for the application:

	<?xml version="1.0" encoding="iso-8859-1"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" 
    pageTitle="Simple Flex Chat" creationComplete="chatSubscriber.subscribe()">

    <!-- Messaging Declarations -->

    <mx:Producer id="chatPublisher" destination="MyTransientTopic" />
    <mx:Consumer id="chatSubscriber" destination="MyTransientTopic" message="receiveChatMessage(event)" />

    <!-- UI Declarations -->

    <mx:Panel title="Simple Flex Chat">
        <mx:TextArea id="output" width="385" height="220" />
        <mx:TextInput id="input" width="385" enter="sendChatMessage()" />
        <mx:ControlBar horizontalAlign="center" width="385">
            <mx:Button id="clearBtn" label="Clear" click="output.text =''" />
        </mx:ControlBar>
    </mx:Panel>

    <!-- Event-Handling Script -->

    <mx:Script>
        <![CDATA[
    
        import mx.messaging.events.MessageEvent;
        import mx.messaging.messages.AsyncMessage;
    
        private function sendChatMessage():void
        {
            var msg:AsyncMessage = new AsyncMessage();
            msg.body = input.text;
            chatPublisher.send(msg);
            input.text = "";
        }

        private function receiveChatMessage(msgEvent:MessageEvent):void
        {
            var msg:AsyncMessage = AsyncMessage(msgEvent.message);
            output.text += msg.body + "\n";
        }

        ]]>
    </mx:Script>

</mx:Application>

Note the use of the <Producer> and <Consumer> tag declarations. Both tags declare which destination they are associated with. The <Consumer> tag also declares which ActionScript method handles all message events dispatched when messages arrive for the consumer. The messaging script, invoked each time the user presses the Enter key with the input text box in focus, composes a new message instance. In this case, it is a basic AsyncMessage (other message types include the RPC messages and data messages). The producer publishes the new message using the producer.send(message) invocation. In the Flex <Application> tag, the creationComplete event handler subscribes the consumer to its destination after all Flex components have been created. Internally, the Flex client and server infrastructure will handle the encoding and transmission of the message, return acknowledge events, handle message correlation, handle the pushing (or potentially polling) of messages to the consumer, and so forth.

This is not a terribly useful chat (it can't even tell who is writing the messages, everyone is left deviously anonymous), but it enables the message flow between multiple clients and the server-side message destination, which is core to the Message Service. I revisit this application and add features using more of the Message Service API below.

Meanwhile, one piece still missing is a declaration related to the destination. In the MXML code above, the producer and consumer both reference the destination by name. But where is this destination created?

Since the destination exists remotely on the server, it is configured in a server-side XML file packaged with the Flex Data Services libraries in a J2EE web application. The configuration of services and destinations is the same across all of the Flex Data Services; that is, whether you are configuring a RPC RemoteObject, a DataService, a WebService or a MessageService component, the format is essentially the same. You declare a set of services in XML, and within each of those services, you configure destinations. You also declare things like security constraints and network channels that you want to make available, as well as any adapters you would like to plug into services, to link them to various back-end resources.

The message destination used by the producer and consumer above is named MyTransientTopic. You configure it as follows. The word transient is in the name because this particular destination is not durable. That is, it will not persist messages to ensure that they are later delivered to consumers that may be offline. If the service goes down, it will not reload its cache from storage. The configuration includes a channel declaration to control which network protocol (or protocols) this message destination will use to transmit messages.

<service id="message-service"
    class="flex.messaging.services.MessageService"
    messageTypes="flex.messaging.messages.AsyncMessage">

    <!-- other destinations snipped -->

    <destination id="MyTransientTopic">
        <properties>
            <server>
                <durable>false</durable>
            </server>
        </properties>
        <channels>
            <channel ref="my-rtmp"/>
        </channels>
    </destination>

</service>

Many optional properties exist that control various network and server behaviors, that enable and control destination clustering, and that configure adapters to link Flex publish-subscribe messaging to back-end messaging systems such as JMS and others. The brief syntax above is only an introduction. As we add additional elements to the example in the following sections, refer to the product reference documentation for comprehensive descriptions of all available options.