web-dev-qa-db-fra.com

ACTIVEMQ - exemple d'abonné éditeur bonjour au monde

Il existe deux programmes: abonné et éditeur ... L'abonné est capable de mettre le message sur le sujet et le message est envoyé avec succès. Lorsque je vérifie le serveur activemq sur mon navigateur, il affiche 1 msg en file d'attente. Mais quand je lance le code consommateur, il ne reçoit pas le message

Voici le code producteur:

import javax.jms.*;

import org.Apache.activemq.ActiveMQConnection;
import org.Apache.activemq.ActiveMQConnectionFactory;

public class producer {

    private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;

    public static void main(String[] args) throws JMSException {

        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
        Connection connection = connectionFactory.createConnection();
        connection.start();

        // JMS messages are sent and received using a Session. We will
        // create here a non-transactional session object. If you want
        // to use transactions you should set the first parameter to 'true'
        Session session = connection.createSession(false,
                Session.AUTO_ACKNOWLEDGE);

        Topic topic = session.createTopic("testt");

        MessageProducer producer = session.createProducer(topic);

        // We will send a small text message saying 'Hello'

        TextMessage message = session.createTextMessage();

        message.setText("HELLO JMS WORLD");
        // Here we are sending the message!
        producer.send(message);
        System.out.println("Sent message '" + message.getText() + "'");

        connection.close();
    }
}

Après avoir exécuté ce code, la sortie sur la console est:

26 Jan, 2012 2:30:04 PM org.Apache.activemq.transport.failover.FailoverTransport doReconnect
INFO: Successfully connected to tcp://localhost:61616
Sent message 'HELLO JMS WORLD'

Et voici le code de la consommation:

import javax.jms.*;

import org.Apache.activemq.ActiveMQConnection;
import org.Apache.activemq.ActiveMQConnectionFactory;

public class consumer {
    // URL of the JMS server
    private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;

    // Name of the topic from which we will receive messages from = " testt"

    public static void main(String[] args) throws JMSException {
        // Getting JMS connection from the server

        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
        Connection connection = connectionFactory.createConnection();
        connection.start();

        Session session = connection.createSession(false,
                Session.AUTO_ACKNOWLEDGE);

        Topic topic = session.createTopic("testt");

        MessageConsumer consumer = session.createConsumer(topic);

        MessageListener listner = new MessageListener() {
            public void onMessage(Message message) {
                try {
                    if (message instanceof TextMessage) {
                        TextMessage textMessage = (TextMessage) message;
                        System.out.println("Received message"
                                + textMessage.getText() + "'");
                    }
                } catch (JMSException e) {
                    System.out.println("Caught:" + e);
                    e.printStackTrace();
                }
            }
        };

        consumer.setMessageListener(listner);
        connection.close();

    }
}    

Après avoir exécuté ce code, il ne montre rien. Quelqu'un peut-il m'aider à surmonter ce problème?

20
Vijet Badigannavar

Votre problème est que votre consommateur s'exécute puis s'arrête immédiatement.

Essayez d'ajouter ceci à votre consommateur:

    consumer.setMessageListener(listner);

    try {
        System.in.read();
    } catch (IOException e) {
        e.printStackTrace();
    }

    connection.close();

Cela attendra jusqu'à ce que vous appuyiez sur une touche avant de vous arrêter.

Autres choses à considérer:

  • Utilisez un bloc enfin pour la fermeture
  • Les conventions de nommage Java encouragent l'utilisation de majuscules pour la première lettre d'une classe
16
Jamie McCrindle

Le problème principal (en plus de la fermeture rapide de l'application) est que vous envoyez à un sujet. Les rubriques ne conservent pas les messages, donc si vous exécutez votre application qui produit puis exécutez le consommateur, le consommateur ne recevra rien car il n'était pas abonné à la rubrique au moment où le message a été envoyé. Si vous résolvez le problème d'arrêt, puis exécutez le consommateur dans un terminal, puis exécutez le producteur, vous devriez alors voir le message reçu par votre consommateur. Si vous souhaitez conserver le message, vous devez utiliser une file d'attente qui conservera le message jusqu'à ce que quelqu'un le consomme.

12
Tim Bish

Votre classe producteur est correcte. Cela fonctionne bien.

Mais, votre consommateur est incorrect et vous devez le modifier.

  • Tout d'abord, ajoutez setClientID ("any_string_value") après avoir créé connection object;

    par exemple: Connection connection = connectionFactory.createConnection(); // need to setClientID value, any string value you wish connection.setClientID("12345");

  • deuxièmement, utilisez la méthode createDurableSubscriber () au lieu de createConsumer () pour transmettre le message via la rubrique.

    MessageConsumer consumer = session.createDurableSubscriber(topic,"SUB1234");

Voici la classe modifiée comsumer:

package mq.test;

import javax.jms.*;

import org.Apache.activemq.ActiveMQConnection;
import org.Apache.activemq.ActiveMQConnectionFactory;

public class consumer {
    // URL of the JMS server
    private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;

    // Name of the topic from which we will receive messages from = " testt"

    public static void main(String[] args) throws JMSException {
        // Getting JMS connection from the server

        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
        Connection connection = connectionFactory.createConnection();

        // need to setClientID value, any string value you wish
        connection.setClientID("12345");

        try{
        connection.start();
        }catch(Exception e){
            System.err.println("NOT CONNECTED!!!");
        }
        Session session = connection.createSession(false,
                Session.AUTO_ACKNOWLEDGE);

        Topic topic = session.createTopic("test_data");

        //need to use createDurableSubscriber() method instead of createConsumer() for topic
        // MessageConsumer consumer = session.createConsumer(topic);
        MessageConsumer consumer = session.createDurableSubscriber(topic,
                "SUB1234");

        MessageListener listner = new MessageListener() {
            public void onMessage(Message message) {
                try {
                    if (message instanceof TextMessage) {
                        TextMessage textMessage = (TextMessage) message;
                        System.out.println("Received message"
                                + textMessage.getText() + "'");
                    }
                } catch (JMSException e) {
                    System.out.println("Caught:" + e);
                    e.printStackTrace();
                }
            }
        };

        consumer.setMessageListener(listner);
        //connection.close();

    }
}

Maintenant, votre code s'exécutera avec succès.

3
mahbub_siddique

juste un peu:

  • travailler avec une file d'attente pas un sujet. les messages dans les rubriques seront supprimés si aucun consommateur n'est disponible, ils ne sont PAS persistants.
  • ajoutez connection.start () après avoir défini l'écouteur de messages. vous devez établir une connexion lorsque tous les consommateurs/producteurs sont correctement configurés.
  • attendez un peu avant de refermer la connexion.

le sujet sera probablement votre source d'échec la plus importante.

2
Laures