2012-07-20 133 views
5

我目前正在为持久订阅编写一个messenger服务(它可能最终会变得不耐用,我们仍在讨论这一点),并且正在寻找一些关于如何处理我们的服务器由于某种原因暂时关闭的场景,我们需要自动重新订阅该主题。下面是它如何连接的示例代码:设置JMS连接以便自动重新连接的理想方法

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(); 
    } 
} 

回答

0

你需要多快的故障检测? 设置您的协议,以确保每个客户端至少每分钟发送一条消息(您需要向通信协议添加一些新的“绒毛”保持消息) - 任何未收到保持消息的客户端都可以安全地承担服务器关闭并开始重新连接。

理想情况下,这种事情最好用UDP​​广播,而不是JMS(用于开销),但我假设你有UDP广播作为选项,你会使用jgroups来做群集检测/故障转移/重新加入您。

+0

如果这就是你要求的,它不一定是瞬间的。无论如何,这可以通过try/catch块来完成吗? – Icebreaker 2012-07-20 17:16:14

+0

仅当底层连接断开时引发某种异常。我不能不告诉你。 – radai 2012-07-22 20:03:32

3

你应该让你的客户implement javax.jmsExceptionListener

这将允许您的客户端在连接丢失时即时接收来自JMS API的回调,即使您的应用程序目前不绑定发布任何内容。

创建Connection后,连接并启动它,请拨打connection.setExceptionListener(myListener)。另请参阅Javadoc Connection