Lost Connections

When the network connection between the client and server is lost, a JMS provider must make every reasonable attempt to re-establish the connection. In the event that the JMS provider cannot automatically reconnect, the provider must notify the client of this condition by throwing an exception when the client invokes a method that would cause network traffic to occur. However, it is reasonable to expect that a JMS client may only be a receiver using the MessageListener interface, and not a producer that makes any outbound publish( ) or send( ) calls. In this case, the client is not invoking JMS methods—it is just listening for messages—so a dropped connection won't be detected.

JMS provides an ExceptionListener interface for trapping a lost connection and notifying the client of this condition. The ExceptionListener is bound to the connection—unlike MessageListeners, which are bound to sessions. The definition of the ExceptionListener is:

public interface ExceptionListener{
	void onException(JMSException exception);
}

It is the responsibility of the JMS provider to call the onException( ) method of all registered ExceptionListeners after making reasonable attempts to reestablish the connection automatically. The JMS client can implement the ExceptionListener so that it can be alerted to a lost connection, and possibly attempt to reestablish the connection manually.

How can the JMS provider call an ExceptionListener if the client has been disconnected? Every JMS provider has some amount of functionality that resides in the client application. We have been referring to this as the client runtime portion of the JMS provider. It is the responsibility of the client runtime to detect the loss of connection and call the ExceptionListener.

The Wholesaler Becomes an ExceptionListener

To make our Wholesaler into an ExceptionListener , we start by changing the formal declaration of the class to implement the javax.jms.ExceptionListener interface:

public class Wholesaler implements 
    javax.jms.MessageListener,
    javax.jms.ExceptionListener   
{
...

Next, we remove the connection setup information from the constructor and isolate it in its own method, establishConnection( ) :

public Wholesaler(String broker, String username, String password){
        mBroker = broker;
        mUsername = username;
        mPassword = password;

        establishConnection( broker, username, password );
}

establishConnection( ) sets up the connection, the publisher, and the subscriber. The new addition is the retry logic on the TopicConnectionFactory's createTopicConnection( ) method, which continually retries the connection every ten seconds until it is established:

private void establishConnection(String broker, String username, 
                                 String password)
{
    ...
    while (connect == null)
    {
            try {
                connect = 
                factory.createTopicConnection (username, password);
            } catch (javax.jms.JMSException jmse)
            {
            try {
                Thread.sleep(10000); 
               } catch (java.lang.InterruptedException ie) { }
               continue;
             }
    }
    System.out.println("
Connection established");
...
}

The establishConnection( ) method then registers the ExceptionListener with the connection via the setExceptionListener( ) method:

connect.setExceptionListener( (javax.jms.ExceptionListener) this);

Last, but not least, is the implementation of the onException( ) listener method. Its task is to call the establishConnection( ) method again to re-establish a connection with the JMS provider:

public void onException ( javax.jms.JMSException jmse)
{
    // Tell the user that there is a problem
    System.err.println ("

There is a problem with the connection.");
    System.err.println ("   JMSException: " + jmse.getMessage( ));
            
    System.err.println ("Please wait while the application tries to "+
                                "reestablish the connection...");
    connect = null;
    establishConnection(mBroker, mUsername, mPassword);
}

When a connection is dropped and reestablished, all of the sessions, queues, publishers, and subscribers need to be reestablished in order for the application to continue normal processing. This is why we isolated all the connection logic in the establishConnection( ) method, so that it can be used during startup and reused if the connection is lost.

JMS does not define any reason codes for a dropped connection. However, a JMS provider may provide a finer level of granularity by defining reason codes. Depending on the host operating system's network settings, it may take a while for the provider to notice that a connection has been dropped. Some providers implement a ping capability as a configurable setting to detect a network loss.

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

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