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 Allegati
56199 Visualizzazioni
Media (3 Voti)
La media del punteggio è 4.33333333333333 stelle su 5.
Commenti
Commenti Autore Data
Hi, As you said "The current implementation... Charanjeet singh Hora 5 marzo 2009 1.21
The Message Bus can be used to exchange... Brave Zhou 3 luglio 2012 2.23
Hi, There is another type of Destination called... Murali Krishna 4 marzo 2014 23.14

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
Inviato il 05/03/09 1.21.
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.
Inviato il 03/07/12 2.23.
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
Inviato il 04/03/14 23.14.