web-dev-qa-db-ja.com

ACTIVEMQ-パブリッシャーサブスクライバーHello Worldの例

サブスクライバーとパブリッシャーの2つのプログラムがあります。サブスクライバーはメッセージをトピックに配置でき、メッセージは正常に送信されます。ブラウザでactivemqサーバーを確認すると、1 msg enqueuedと表示されます。しかし、コンシューマコードを実行すると、メッセージを受信しません

プロデューサーコードは次のとおりです。

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

このコードを実行すると、コンソールでの出力は次のようになります。

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'

そして、ここに消費者コードがあります:

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

    }
}    

このコードを実行した後、何も表示されません。誰かが私を助けてこの問題を克服できますか?

20

あなたの問題は、あなたの消費者が走っていて、すぐにシャットダウンすることです。

これを消費者に追加してみてください:

    consumer.setMessageListener(listner);

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

    connection.close();

これは、停止する前にキーを押すまで待機します。

考慮すべきその他の事項:

  • クローズにはfinallyブロックを使用します
  • Javaの命名規則では、クラスの最初の文字に大文字を使用することを推奨しています
16
Jamie McCrindle

主な問題(アプリがすぐに終了することを除く)は、トピックに送信することです。トピックはメッセージを保持しないため、コンシューマを生成して実行するアプリケーションを実行すると、メッセージが送信された時点でトピックにサブスクライブされていなかったため、コンシューマは何も受信しません。シャットダウンの問題を修正し、1つのターミナルでコンシューマーを実行してからプロデューサーを実行すると、コンシューマーが受信したメッセージが表示されます。メッセージを保持したい場合は、誰かがそれを消費するまでメッセージを保持するキューを使用する必要があります。

12
Tim Bish

プロデューサークラスは正しいです。スムーズに実行されます。

しかし、consumerが正しくないため、修正する必要があります。

  • まず、接続オブジェクトの作成後にsetClientID( "any_string_value")を追加します。

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

  • 次に、トピック経由でメッセージを送信するためにcreateConsumer()の代わりにcreateDurableSubscriber()メソッドを使用します。

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

変更された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();

    }
}

これで、コードが正常に実行されます。

3
mahbub_siddique

ほんの一部:

  • トピックではなくキューを操作します。トピック内のメッセージは、利用可能なコンシューマがなくなると破棄され、永続化されません。
  • メッセージリスナの設定後にconnection.start()を追加します。すべてのコンシューマ/プロデューサが適切に設定されたら、接続を開始する必要があります。
  • 接続を再び閉じる前に、しばらく待ってください。

トピックはおそらくあなたの最も重要な失敗の原因になります。

2
Laures