Purposes #

The Message Bus can be used to exchange messages between Liferay and other web applications, including deployed portlets and plugins in general.

The developer can add Destinations to the Message Bus, for each Destination you can register several MessageListeners. The client sends a message to a Destination and the Message Bus will deliver this message to every MessageListener that is listening to this Destination.

The current implementation doesn't allow to send remote messages.

The Message Bus has some similarities with JMS but it is much simpler and don't provide all the features that JMS does.

Example #

- A client sends a message to a destination called ""destinationName".

- The Message Bus iterates over every MessageListener registered to "destinationName".

- For each MessageListener, call its receive(String message) method.

Benefits #

- Only String messages are exchanged, this provides a loose coupling between message producers and consumers, for this reason you won't have class loading issues. The Message Bus is located in portal-kernel, in the global class loader, then, every deployed webapp can use it.

- You can send messages asynchronously and synchronously. Asynchronous message means that you send it and forget, the Message Bus will process your message in a different Thread. Synchronous message means that you send it and your Thread will be waiting for an answer.

- The String can be in any format, as long as producers and consumers understand this format. We generally serialize and deserialize objects to JSON.

Code examples #

Adding a Destination #

 com.liferay.portal.kernel.messaging.Destination destination = new SerialDestination("destinationName");
 destination.afterPropertiesSet();
 MessageBusUtil.addDestination(destination);

First, you create a Destination and give a name to it (in this case "destinationName", we usually define destination names constants in DestinatioNames class), then you call the "afterPropertiesSet()" function to make the destination work. After that you can add it to the Message Bus.

A Destination can be added anywhere, either by the message consumer or producer.

There is another type of Destination called ParallelDestination which you can set the initial and maximum sizes of the ThreadPool used by the Message Bus. SerialDestination extends ParallelDestination and uses a ThreadPool with size 1 to dispatch messages. You use SerialDestination when you know that the requests will be sent in series, and ParallelDestination when you need to send messages in parallel.

Adding a MessageListener #

Create a class that implements com.liferay.portal.kernel.messaging.MessageListener, you must implement the following method:

 public interface MessageListener {
    public void receive(Message message);
 }

Register the MessageListener that you created to the Message Bus, you can do this in 2 ways:

 MessageBusUtil.registerMessageListener("destinationName", myListener);

or if you still have a reference to the Destination:

 destination.register(myListener);

Note: The message listener can only be registered by the message consumer, otherwise you are going to have problems with the class loader.

Sending messages to myListener #

Asynchronous message:

 Message myMessage = new Message();
 myMessage.put("messageName",anObject);
 MessageBusUtil.sendMessage("destinationName",  myMessage);

Synchronous message:

 String reply = MessageBusUtil.sendSynchronizedMessage("destinationName",  "myMessage");

In this case, if the MessageListener takes more than 1 second to answer the Message Bus will throw a MessageBusException, there is a different sendSynchronizedMessage method where you can pass the timeout as a parameter, if timeout is -1 the Message Bus will wait until it gets an answer no matter how long it will take, it's not recommended to use -1 as it can lock your thread.

In order to answer to a synchronous message your MessageListener needs to do the following:

 public void receive(String message) {
 JSONObject jsonObj = new JSONObject(message);
 String responseDestination = jsonObj.optString(lfrResponseDestination");
 String responseId = jsonObj.optString("lfrResponseId");

... process the message ....

then, send a reply:

 JSONObject jsonObj = new JSONObject();
 JSONUtil.put(jsonObj, "lfrResponseId", responseId);
 JSONUtil.put(jsonObj, "message", "myReply");
 MessageBusUtil.sendMessage(responseDestination, jsonObj.toString());

Configuration #

You can override the default Message Bus implementation by changing misc-spring.xml:

 <bean id="com.liferay.portal.kernel.messaging.MessageBus" class="com.liferay.portal.messaging.PortalMessageBus" lazy-init="true">
   <property name="messageBus">
     <bean class="com.liferay.portal.kernel.messaging.DefaultMessageBus" lazy-init="true"  
   </property>
 </bean>
 <bean id="com.liferay.portal.kernel.messaging.MessageSender" class="com.liferay.portal.kernel.messaging.DefaultMessageSender" lazy-init="true">
   <property name="messageBus">
     <ref bean="com.liferay.portal.kernel.messaging.MessageBus" />
   </property>
 </bean>

Where the Message Bus is used? #

You can see more examples if you take a look at our SearchEngine and SchedulerEngine services.

0 Attachments
67297 Views
Average (3 Votes)
The average rating is 4.33333333333333 stars out of 5.
Comments
Threaded Replies Author Date
Hi, As you said "The current implementation... Charanjeet singh Hora March 5, 2009 1:21 AM
The Message Bus can be used to exchange... Brave Zhou July 3, 2012 2:23 AM
Hi, There is another type of Destination called... Murali Krishna March 4, 2014 11:14 PM

Hi,

As you said "The current implementation doesn't allow to send remote messages
", how can I use message bus if I am using liferay in clustered environment?

How can I send/receive message accross different instances of liferay server in clustering environment.

PS: I am using liferay 5.2
Posted on 3/5/09 1:21 AM.
The Message Bus can be used to exchange messages between Liferay and *other web applications*.

Does this mean that the common web application(Not liferay portlet) can also send message to liferay's message bus? How? Can you give me a example.
Posted on 7/3/12 2:23 AM.
Hi,
There is another type of Destination called ParallelDestination which you can set the initial and maximum sizes of the ThreadPool used by the Message Bus.

can you please give more explanation on this ?

Murali
Posted on 3/4/14 11:14 PM.