2016-03-02 1 views
0

J'ai une application client riche Java qui enregistre un abonnement durable sur un sujet HornetQ JMS distant au démarrage. Toutefois, si le serveur redémarre, la connexion est perdue et ne peut être restaurée qu'en redémarrant l'application cliente. Cela conduit à des situations confuses dans lesquelles les messages JMS ne sont pas reçus et après le redémarrage d'un client, un grand nombre de messages sont reçus en même temps.Comment savoir quand la connexion à un sujet JMS est perdue?

Une solution simple pour restaurer la connexion serait d'exécuter une minuterie pour vérifier périodiquement si la connexion est toujours valide et essayer de se reconnecter autrement. Le serveur peut également envoyer un signal de présence au client et tenter de se reconnecter si aucun signal de présence n'est reçu après un certain délai (comme indiqué dans ce code answer).

Mais les deux semblent des approches maladroites à ce problème et donc je voudrais savoir s'il y a une meilleure solution pour découvrir que la connexion n'est plus disponible?

Répondre

0

Pour être informé de la déconnexion, vous devez enregistrer un ExceptionListener sur votre TopicConnection avant de démarrer la connexion.

private void subscribe() throws JMSException { 

    // get context/create connection and session/etc. 
    TopicConnection connection = ... 

    connection.setExceptionListener(this::handleExceptions); 
    connection.start(); 
} 

Dans le ExceptionListener vous pouvez vérifier le code d'erreur de la JMSException reçue. (Les codes d'erreur sont spécifiques au fournisseur)
Dans le cas de HornetQ, le code d'erreur DISCONNECT est reçu après la perte de la connexion. Ensuite, vous pouvez démarrer un temporisateur à annulation automatique qui tente de se reconnecter toutes les x secondes jusqu'à ce qu'il réussisse.

private static final long SUBSCRIBE_RETRY_TIME_OUT_IN_MILLIS = 60000; 

private void tryConnect() { 

    final Timer timer = new Timer("JMS-Topic-Reconnection-Timer", true); 
    final TimerTask timerTask = new TimerTask() { 

     @Override 
     public void run() { 
      try { 
       subscribe(); 
       // cancel the timer, after the subscription succeeds 
       timer.cancel(); 
      } 
      catch (final Exception e) { 
       logger.info("reconnect to jms topic failed: {}", e.getMessage()); 
      } 
     } 
    }; 
    timer.schedule(timerTask, SUBSCRIBE_RETRY_TIME_OUT_IN_MILLIS, SUBSCRIBE_RETRY_TIME_OUT_IN_MILLIS); 
}