Question

I'm currently programming a messenger service for durable subscriptions (it might end up being non durable we are still discussing that) and I was looking for some suggestions on how to handle a scenario where our server goes temporarily down for whatever reason and we need to resubscribe to the topic automatically. Here is sample code of how it connects:

public void DurableChatter(String broker, String username, String password)
{
    javax.jms.MessageProducer publisher = null;
    javax.jms.MessageConsumer subscriber = null;
    javax.jms.Topic topic = null;

    //Create a connection:
    try{
        javax.jms.ConnectionFactory factory;
        factory = (new progress.message.jclient.ConnectionFactory (broker));
        connection = factory.createConnection (username, password);

        //Durable Subscriptions are indexed by username, clientID and subscription name
        //It is a good proactice to set the clientID:
        connection.setClientID(CLIENT_ID);
        pubSession = connection.createSession(false,javax.jms.Session.AUTO_ACKNOWLEDGE);
        subSession = connection.createSession(false,javax.jms.Session.AUTO_ACKNOWLEDGE);
    }
    catch (javax.jms.JMSException jmse){
        System.err.println ("Error: Cannot connect to Broker - " + broker);
        jmse.printStackTrace();
        System.exit(1);
    }

    //Create Publisher and Durable Subscriber:
    try{

        topic = pubSession.createTopic(APP_TOPIC);
        subscriber = subSession.createDurableSubscriber(topic, "SampleSubscription");
        subscriber.setMessageListener(this);
        publisher = pubSession.createProducer(topic);
        connection.start();
    }
    catch (javax.jms.JMSException jmse){
        System.out.println("Error: connection not started.");
        jmse.printStackTrace();
        System.exit(1);
    }

    //Wait for user input

    try
    {
        System.out.println("Enter text to send as message and press enter.");
        java.io.BufferedReader stdin =
            new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
        while (true)
        {
            String s = stdin.readLine();

            if(s == null){
                exit();
            }
            else if (s.length()>0)
            {
                try
                {
                    javax.jms.TextMessage msg = pubSession.createTextMessage();
                    msg.setText(username + ": " + s);
                    //Publish the message persistantly:
                    publisher.send(
                        msg,                               //message
                        javax.jms.DeliveryMode.PERSISTENT, //publish persistantly
                        javax.jms.Message.DEFAULT_PRIORITY,//priority
                        MESSAGE_LIFESPAN);                 //Time to Live
                }
                catch (javax.jms.JMSException jmse){
                    System.err.println("Error publishing message:" + jmse.getMessage());
                }
            }
        }
    }
    catch (java.io.IOException ioe)
    {
        ioe.printStackTrace();
    }
}
Was it helpful?

Solution

how fast do you need failure detection to be? set up your protocol so that it guarantees every client is sent a message at least once a minute (you'll need to add some new "fluff" keepalive message to your communication protocol) - any client not receiving a keepalive message can safely assume the server is down and begin reconnecting.

ideally this sort of thing is best done with UDP broadcast and not JMS (for the overhead), but i assume if you have UDP broadcast as an option you'd use jgroups to do you cluster detecion/failover/rejoin for you.

OTHER TIPS

You should make your client implement javax.jmsExceptionListener.

This will allow your client to instantly receive a callback from the JMS API when the connection is lost, even if your application is not tying to publish anything at the moment.

After creating the Connection, connecting and starting it, call connection.setExceptionListener(myListener). See also the Javadoc for Connection.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top