Reputation: 287
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();
}
}
Upvotes: 5
Views: 4755
Reputation: 2715
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.
Upvotes: 3
Reputation: 24192
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.
Upvotes: 0