LiveCycle Data Services Messaging and Presence Service

July 11, 2008 – 3:07 am

Working lately on some collaboration apps i got the need for a unified service running both messaging and presence functionalities. Prior to using LCDS for presence i was using Flash Media Server where you have the SharedObject for syncronizing data between multiple clients. But this is not a very comfortable situation as you have to connect and subscribe to two different services (that possible don’t even run on the same machine). When one fails the whole system fails as both are critical for the system.
So i’ve started looking on LCDS area for a presence functionality. The only bad thing i will say about LCDS is it’s lack of documentation. This lack has become smaller with the new versions but still you will need some scratch in the head to get all the informations you need. Anyway let’s see how you can have both messaging and presence in a LiveCycle destination.

First of all lets cover the server side part. You will need to copy the messaging.jar listed below into the lib folder on your server hosting the LCDS solution. Now go edit the messaging-config.xml file from the WEB-INF/flex folder. What you need to add is a destination, a declaration for the messaging service you want to run. A default destination would look something like this:

<destination id="INSERT_YOUR_DESTINATION_NAME_HERE">

            <properties>
                    <network>
                        <session-timeout>0</session-timeout>
                </network>

                    <server>
                        <max-cache-size>1000</max-cache-size>
                        <message-time-to-live>0</message-time-to-live>
                        <durable>false</durable>
                        <allow-subtopics>true</allow-subtopics>
                        <subtopic-separator>.</subtopic-separator>
                    </server>
            </properties>

            <channels>
                    <channel ref="my-rtmp"/>
            </channels>

</destination>

If you scroll up you will see the tag listing some definitions for adapters. Default implemented adapters used by LCDS are actionscript and jms adapter. Keep this open for a minute.
The messaging “framework” has at it’s core two main classes, the “MessageAdapter” on the Java part and the “MessageService” on the ActionScript part. As you probably already guessed we will add a new adapter definition and use the custom adapter for our destination. Adapter definition looks like this:

<adapter-definition id="messageAdapter" class="com.eyepartner.messaging.services.MessageAdapter" />

Now in your destination you need so specify what adapter to run. If you don’t specify an adapter, the default adapter will be used (the one that has default=”true” in it’s adapter-definition tag). Adapter definition in destination looks like this:

<adapter ref="messageAdapter"/>

The complete adapters tag should look like this:

<adapters>
            <adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" />
            <adapter-definition id="jms" class="flex.messaging.services.messaging.adapters.JMSAdapter" default="true"/>
    <adapter-definition id="messageAdapter" class="com.eyepartner.messaging.services.MessageAdapter" />
</adapters>

And the complete destination tag should look like this:

<destination id="INSERT_YOUR_DESTINATION_NAME_HERE">

            <properties>
                    <network>
                        <session-timeout>0</session-timeout>
                </network>

                    <server>
                        <max-cache-size>1000</max-cache-size>
                        <message-time-to-live>0</message-time-to-live>
                        <durable>false</durable>
                        <allow-subtopics>true</allow-subtopics>
                        <subtopic-separator>.</subtopic-separator>
                    </server>
            </properties>

            <channels>
                    <channel ref="my-rtmp"/>
            </channels>
   
    <adapter ref="messageAdapter"/>

</destination>

That’s pretty much it on the server side. Don’t forget to replace INSERT_YOUR_DESTINATION_NAME_HERE with your desired destination name, you will need it on the client side which will cover right now.

On the client side, the do-all-things class is com.eyepartner.messaging.services.MessageService. For the initialization part you will need to set the following things:

- messageService.channelId: this is set default to “my-rtmp” so probably you won’t need to set it
- messageService.channelURI: this is your rtmp endpoint set on services-confing.xml for channel-definition. Usually looks like:
rtmp://[SERVER_ADDRESS]:2038
- messageService.destination: this is your if for the destination from messaging-config.xml ()

optionally you can set messageService.subtopic to subscribe to a subtopic for destination. This is handy when you need multiple “rooms” for your service using same destination.

The way you subscribe to a service is by messageService.subscribe() method that takes a MessageClient param. Class com.eyepartner.messaging.MessageClient has basic functionality for id and name. You can extend it to add more functionalities but make sure you create it’s java counterpart for serialization/deserialization between layers.

Once you subscribe to the service the way you receive messages and presence informations is simple. Lets cover the messaging part first. The class on which you need messaging listeners need to implement the IMessageListener interface and the method where messages are dispatched is messageReceived( client:MessageClient, message:Object ). Make sure you call messageService.addMessageListener( this ) to register the class for messages.

For the presence functionalities you have two options. First is simply using messageService.clients collection where all clients are stored (clients running on same subtopic). The second is using the IPresenceListener interface, same as IMessageListener. Methods called are clientConnected( client:MessageClient ) and clientDisconnected( client:MessageClient ). Again make sure you call messageService.addPresenceListener( this ) to register the class for presence.

That should be pretty much it on the client side too. Here are the .swc and .jar files along with source codes for both. Labeled under EyePartner copyrights so all bugs are from the company not me (o_0).

flex-lib
fds-lib
flex-src
java-lib
java-src

Here’s a demo i’ve put together using the messaging services:

  1. 2 Responses to “LiveCycle Data Services Messaging and Presence Service”

  2. Awesome post man, your tutorials rock!
    Cheers

    By Cristian on Jul 12, 2008

  3. Found a bug with the chat demo. If you’re logged on and don’t logoff correctly (say you lose internet connection or power), two bad things happen:

    It detects the disconnection fine, but when you reconnect, the online clients list is blank. Once you reload the page, however, the online clients list shows some users… But this brings up the second issue - the server still thinks the previous user(s) that lost connection are around! I had two clients open in 2 different browsers, killed my network connection, and then brought it back. Now I’m looking at three “online clients” but only one of them is valid, the other two are ghost users..

    I only mention this because I’ve found it very difficult finding a solution for this type of issue using Blaze (or LCDS), so a working example that solves all these types of problems would be awesome. But such a perfect example doesn’t seem to exist yet!

    By Ansury on Aug 31, 2008

Post a Comment