(三)ActiveMQ之發布- 訂閱消息模式實現


一、概念

  • 發布者/訂閱者模型支持向一個特定的消息主題發布消息。0或多個訂閱者可能對接收來自特定消息主題的消息感興趣。在這種模型下,發布者和訂閱者彼此不知道對方。這種模式好比是匿名公告板。這種模式被概括為:多個消費者可以獲得消息
  • 在發布者和訂閱者之間存在時間依賴性。發布者需要建立一個訂閱(subscription),以便客戶能夠訂閱。訂閱者必須保持持續的活動狀態以接收消息,除非訂閱者建立了持久的訂閱。在那種情況下,在訂閱者未連接時發布的消息將在訂閱者重新連接時重新發布。

二、案例

  2.1  消息生產者-消息發布者

package com.shyroke.firstActiveMQ2;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

/**
 * 消息生產者
 * @author Administrator
 *
 */
public class JMSProducer {

    private static final String USERNAME=ActiveMQConnection.DEFAULT_USER; // 默認的連接用戶名
    private static final String PASSWORD=ActiveMQConnection.DEFAULT_PASSWORD; // 默認的連接密碼
    private static final String BROKEURL=ActiveMQConnection.DEFAULT_BROKER_URL; // 默認的連接地址
    private static final int SENDNUM=10; // 發送的消息數量
    
    public static void main(String[] args) {
        
        ConnectionFactory connectionFactory; // 連接工廠
        Connection connection = null; // 連接
        Session session; // 會話 接受或者發送消息的線程
        Destination destination; // 消息的目的地
        MessageProducer messageProducer; // 消息生產者
        
        // 實例化連接工廠
        connectionFactory=new ActiveMQConnectionFactory(JMSProducer.USERNAME, JMSProducer.PASSWORD, JMSProducer.BROKEURL);
        
        try {
            connection=connectionFactory.createConnection(); // 通過連接工廠獲取連接
            connection.start(); // 啟動連接
            session=connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); // 創建Session
//            destination=session.createQueue("FirstQueue1"); // 創建消息隊列
            destination=session.createTopic("firstTopic");
            messageProducer=session.createProducer(destination); // 創建消息生產者
            sendMessage(session, messageProducer); // 發送消息
            session.commit();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally{
            if(connection!=null){
                try {
                    connection.close();
                } catch (JMSException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    
    /**
     * 發送消息
     * @param session
     * @param messageProducer
     * @throws Exception
     */
    public static void sendMessage(Session session,MessageProducer messageProducer)throws Exception{
        for(int i=0;i<JMSProducer.SENDNUM;i++){
            TextMessage message=session.createTextMessage("ActiveMQ 發布的消息"+i);
            System.out.println("發送消息:"+"ActiveMQ 發布的消息"+i);
            messageProducer.send(message);
        }
    }
}

 

  2.2  消息消費者-消息訂閱者一

package com.shyroke.firstActiveMQ2;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class JMSConsumer {
    private static final String USERNAME=ActiveMQConnection.DEFAULT_USER; // 默認的連接用戶名
    private static final String PASSWORD=ActiveMQConnection.DEFAULT_PASSWORD; // 默認的連接密碼
    private static final String BROKEURL=ActiveMQConnection.DEFAULT_BROKER_URL; // 默認的連接地址
    
    public static void main(String[] args) {
        
        ConnectionFactory connectionFactory; // 連接工廠
        Connection connection = null; // 連接
        Session session; // 會話 接受或者發送消息的線程
        Destination destination; // 消息的目的地
        MessageConsumer consumer; //創建消費者
        
        // 實例化連接工廠
        connectionFactory=new ActiveMQConnectionFactory(JMSConsumer.USERNAME, JMSConsumer.PASSWORD, JMSConsumer.BROKEURL);
        
        try {
            connection=connectionFactory.createConnection(); // 通過連接工廠獲取連接
            connection.start(); // 啟動連接
            /**
             * 這里的最好使用Boolean.FALSE,如果是用true則必須commit才能生效,且http://127.0.0.1:8161/admin管理頁面才會更新消息隊列的變化情況。
             */
            session=connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // 創建Session
//            destination=session.createQueue("FirstQueue1"); // 創建消息隊列
            destination=session.createTopic("firstTopic");
            consumer=session.createConsumer(destination);
            consumer.setMessageListener(new MyListener()); // 注冊消息監聽
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
    

    
}
  • 監聽器1

package com.shyroke.firstActiveMQ2;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

public class MyListener implements MessageListener {

    public void onMessage(Message message) {
        try {
            System.out.println("訂閱者一收到的消息:"+((TextMessage)message).getText());
        } catch (JMSException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

 

  2.3  消息消費者-消息訂閱者二

package com.shyroke.firstActiveMQ2;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class JMSConsumer2 {
    private static final String USERNAME=ActiveMQConnection.DEFAULT_USER; // 默認的連接用戶名
    private static final String PASSWORD=ActiveMQConnection.DEFAULT_PASSWORD; // 默認的連接密碼
    private static final String BROKEURL=ActiveMQConnection.DEFAULT_BROKER_URL; // 默認的連接地址
    
    public static void main(String[] args) {
        
        ConnectionFactory connectionFactory; // 連接工廠
        Connection connection = null; // 連接
        Session session; // 會話 接受或者發送消息的線程
        Destination destination; // 消息的目的地
        MessageConsumer consumer; //創建消費者
        
        // 實例化連接工廠
        connectionFactory=new ActiveMQConnectionFactory(JMSConsumer2.USERNAME, JMSConsumer2.PASSWORD, JMSConsumer2.BROKEURL);
        
        try {
            connection=connectionFactory.createConnection(); // 通過連接工廠獲取連接
            connection.start(); // 啟動連接
            /**
             * 這里的最好使用Boolean.FALSE,如果是用true則必須commit才能生效,且http://127.0.0.1:8161/admin管理頁面才會更新消息隊列的變化情況。
             */
            session=connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // 創建Session
//            destination=session.createQueue("FirstQueue1"); // 創建消息隊列
            destination=session.createTopic("firstTopic");
            consumer=session.createConsumer(destination);
            consumer.setMessageListener(new MyListener2()); // 注冊消息監聽
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
}
  • 監聽器2

package com.shyroke.firstActiveMQ2;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

public class MyListener implements MessageListener {

    public void onMessage(Message message) {
        try {
            System.out.println("訂閱者一收到的消息:"+((TextMessage)message).getText());
        } catch (JMSException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

 

  • 測試以及結果

發布- 訂閱消息模式首先必須訂閱者先訂閱服務,然后發布者再發布消息,最后訂閱者受到服務消息。

所以本章我們先執行消息訂閱者一和消息訂閱者二的代碼然后查看ActiveMQ的管理界面:

如圖可見,訂閱者已經注冊成功,然后再發布者發布消息:

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM