Simple Synchronous Receiver Example

The code for a simple synchronous receiver is very similar to that of the sender method already presented. There are two differences in constructing the QueueReceiver object.

The first one is obvious; a QueueReceiver is created instead of a QueueSender. Like createSender(), the createReceiver() method throws a JMSException if the session fails to create a receiver, and an InvalidDestinationException if an invalid queue is specified.

The second difference is that this time there is a call to the connection's start() method, which starts (or restarts) delivery of incoming messages for this receiver. Calling start() twice has no detrimental effect. It also has no effect on the connection's ability to send messages. The start() method may throw a JMSException if an internal error occurs. A receiver can use Connection.stop() to temporarily suspend delivery of messages.

The message is received using the synchronous receive() method, as shown next. This may throw a JMSException.

Message msgBody =queueReceiver.receive();
if (msgBody instanceof TextMessage) {
    String text = ((TextMessage) msgBody).getText();
}

If there is no message in the queue, the receive() method blocks until a message is available. There are two alternative versions of the receive() method:

  • receiveNoWait() Retrieves the next message available, or returns null if one is not immediately available

  • receive(long timeout) Retrieves the next message produced within the period of the timeout

Receive JMS Text Message Example

The code for the entire point-to-point receiver example is shown in Listing 9.2.

Listing 9.2. Complete Code for Point-to-Point Queue Receiver
 1: import javax.naming.*;
 2: import javax.jms.*;
 3:
 4: public class PTPReceiver {
 5:
 6:     private QueueConnection queueConnection;
 7:     private QueueSession queueSession;
 8:     private QueueReceiver queueReceiver;
 9:     private Queue queue;
10:
11:     public static void main(String[] args) {
12:         try {
13:             PTPReceiver receiver = new PTPReceiver();
14:             System.out.println ("Receiver running");
15:             String textMsg = receiver.consumeMessage();
16:             if (textMsg != null)
17:                 System.out.println ("Received: " + textMsg);
18:             receiver.close();
19:         }
20:         catch(Exception ex) {
21:              System.err.println("Exception in PTPReceiver: " + ex);
22:         }
23:     }
24:
25:     public PTPReceiver() throws JMSException, NamingException {
26:         Context context = new InitialContext();
27:         QueueConnectionFactory queueFactory = (QueueConnectionFactory)context.lookup
("jms/QueueConnectionFactory");
28:         queueConnection = queueFactory.createQueueConnection();
29:         queueSession = queueConnection.createQueueSession(false, Session
.AUTO_ACKNOWLEDGE);
30:         queue = (Queue)context.lookup("jms/firstQueue");
31:         queueReceiver = queueSession.createReceiver(queue);
32:         queueConnection.start();
33:     }
34:
35:     public String consumeMessage () throws JMSException {
36:         String text = null;
37:         Message msgBody = queueReceiver.receive();
38:         if (msgBody instanceof TextMessage) {
39:             text = ((TextMessage) msgBody).getText();
40:         }
41:         return text;
42:     }
43:
44:     public void close() throws JMSException {
45:         queueReceiver.close();
46:         queueSession.close();
47:         queueConnection.close();
48:     }
49: }
						

Run this program from the command line. If you have previously used PTPSender to put messages in the queue, these will now be displayed.

Asynchronous Messaging

For many applications, the synchronous mechanism is not suitable and an asynchronous technique is required. To implement this in JMS, you need to register an object that implements the MessageListener interface. The JMS provider invokes this object's onMessage() each time a message is available at the destination.

The receiver example will now be extended to support asynchronous messaging. Because this is a simple example, the listener is implemented in the same class.

public class PTPListener implements MessageListener {

The message listener is registered with a specific QueueReceiver by using the setMessageListener() method before calling the connection's start() method. The following extra line is required in the constructor:

queueReceiver.setMessageListener(this);

Messages might be missed if you call start() before you register the message listener.

To actually receive the messages, the MessageListener interface provides a single onMessage() method. The JMS provider calls your implementation of this method when it has a message to deliver. The following is an example onMessage() method:

public void onMessage(Message message) {
    try {
        if (message instanceof TextMessage) {
             String text = ((TextMessage) message).getText();
             System.out.println("Received: " + text);
        }
    }
    catch(JMSException ex) {
        System.err.println("Exception in OnMessage: " + ex);
    }
}

The onMessage() method should handle all exceptions. If onMessage() throws an exception, the signature will be altered and, therefore, not recognized.

In the main() method, the QueueReceiver object is initialized as before, but this time there is no call to a synchronous receive() method.

public static void main(String[] args) {
    System.out.println ("Listener running");
    try {
        PTPListener receiver = new PTPListener();
        Thread.currentThread().sleep(2000);
        receiver.close();
    }
    catch(Exception ex) {
        System.err.println("Exception in PTPListener: " + ex);
    }
}

A sleep has been placed in the main body to allow time for messages to be handled.

Normally, the main() method would sleep for a long period or do other processing and therefore requires some way to determine when message processing is finished. Typically, a shutdown message is sent or the user interface is used to close the application. For brevity, this code is not included here.

Asynchronous Exception Handling

If you register an ExceptionListener with a connection, your application will be asynchronously informed of problems. If a client only consumes a message, this may be the only way it can be informed that the connection has failed.

The JMS provider will call the listener's onException() method, passing it a JMSException describing the problem.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.75.70