ActiveMQ实战(二)--ActiveMQ的通信方式之P2P点对点通信(point-to-point)

一、简介


点对点的消息发送方式主要建立在 Message Queue,Sender,receiver上,Message Queue 存贮消息,Sender 发送消息,receive接收消息.具体点就是Sender Client发送Message Queue ,而 receiver Client从Queue中接收消息和"发送消息已接受"到Queue,确认消息接收。消息发送客户端与接收客户端没有时间上的依赖,发送客户端可以在任何时刻发送信息到Queue,而不需要知道接收客户端是不是在运行。




P2P的过程理解起来很简单。它好比是两个人打电话,这两个人是独享这一条通信链路的。一方发送消息,另外一方接收,就这么简单,在P2P里一个queue只有一个发送者和一个接收者。


点对点通信实现有两种方式:


第一种:直接Receive方式
第二种:使用Listener监听方式



二、实现步骤


1.开启ActiveMQ服务
2.创建生产者,用于向指定队列发送测试数据 
3.创建消费者-Receive方式,消费由生产者发送的队列的消息 
4.创建消费者-Listener方式,消费由生产者发送的队列的消息 
5.查看ActiveMQ后台,显示,生产者,消费者及消息的接收和处理状态


三、实战点对点通信


A)直接Receive方式


ActiveMQ消息签收机制:


客戶端成功接收一条消息的标志是一条消息被签收,成功应答。


消息的签收情形分两种:


1、带事务的session
   如果session带有事务,并且事务成功提交,则消息被自动签收。如果事务回滚,则消息会被再次传送。


2、不带事务的session


   不带事务的session的签收方式,取决于session的配置。


ActiveMQ支持一下三种模式:


   Session.AUTO_ACKNOWLEDGE  消息自动签收
   Session.CLIENT_ACKNOWLEDGE  客戶端调用acknowledge方法手动签收
   Session.DUPS_OK_ACKNOWLEDGE 不是必须签收,消息可能会重复发送。在第二次重新传送消息的时候,消息
 

1.Session.AUTO_ACKNOWLEDGE。当客户成功的从receive方法返回的时候,或者从MessageListener.onMessage方法成功返回的时候,会话自动确认客户收到的消息。

2.Session.CLIENT_ACKNOWLEDGE。客户通过消息的acknowledge 方法确认消息。需要注意的是,在这种模式中,确认是在会话层上进行:确认一个被消费的消息将自动确认所有已被会话消费的消息。例如,如果一个消息消费者消费了10 个消息,然后确认第5 个消息,那么所有10 个消息都被确认。

3.Session.DUPS_ACKNOWLEDGE。该选择只是会话迟钝第确认消息的提交。如果JMS provider 失败,那么可能会导致一些重复的消息。如果是重复的消息,那么JMS provider 必须把消息头的JMSRedelivered 字段设置为true。



1)生产者

package com.fendo.mq;

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.spring.ActiveMQConnectionFactory;


/**
 * 消息生产者
 * @author fendo
 *
 */

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 org.apache.activemq.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("HelloWorld");//创建一个HelloWorld的消息队列
			messageProducer=session.createProducer(destination);//创建消息生产者
			sendMessage(session, messageProducer);//发送消息
			session.commit();
		} catch (JMSException e) {
			e.printStackTrace();
		}finally {
			if(connection!=null) {
				try {
					connection.close();
				} catch (JMSException e) {
					e.printStackTrace();
				}
			}
		}
		
		
		
	}

	/**
	 * 发送消息
	 * @author fendo
	 * @param session
	 * @param messageProducer
	 * @throws JMSException
	 */
	public static void sendMessage(Session session ,MessageProducer messageProducer) throws JMSException {
		for(int i=0;i<JMSProducer.SENDNUM;i++) {
			TextMessage message=session.createTextMessage("ActiveMQ发送的消息:"+i);
			System.out.println("发送的消息:"+"ActiveMQ发送的消息:"+i);
			messageProducer.send(message);
		}
	}
}


2)消费者

package com.fendo.mq;

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

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

/**
 * 消费者
 * @author fendo
 *
 */
public class JMSConsumer_Receive {

	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 messageConsumer; // 消息的消费者
		
		// 实例化连接工厂
		connectionFactory=new ActiveMQConnectionFactory(JMSConsumer_Receive.USERNAME, JMSConsumer_Receive.PASSWORD, JMSConsumer_Receive.BROKEURL);
				
		try {
			connection=connectionFactory.createConnection();  // 通过连接工厂获取连接
			connection.start(); // 启动连接
			session=connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // 创建Session
			destination=session.createQueue("HelloWorld");  // 创建连接的消息队列 (注意:队列名要和生产者那边相同)
			messageConsumer=session.createConsumer(destination); // 创建消息消费者
			while(true){
				TextMessage textMessage=(TextMessage)messageConsumer.receive(100000);//设置多少秒接受一次
				if(textMessage!=null){
					System.out.println("收到的消息:"+textMessage.getText());
				}else{
					break;
				}
			}
		} catch (JMSException e) {
			e.printStackTrace();
		}finally {
			try {
				connection.close();
			} catch (JMSException e) {
				e.printStackTrace();
			}
		}
		
	}

}

B)使用Listener监听方式


1)生产者

生产者类不变,和上面一样。


2)消费者

package com.fendo.mq;

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

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

/**
 * 消费者
 * @author fendo
 *
 */
public class JMSConsumer_Listener {

	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 messageConsumer; // 消息的消费者
		
		// 实例化连接工厂
		connectionFactory=new ActiveMQConnectionFactory(JMSConsumer_Listener.USERNAME, JMSConsumer_Listener.PASSWORD, JMSConsumer_Listener.BROKEURL);
				
		try {
			connection=connectionFactory.createConnection();  // 通过连接工厂获取连接
			connection.start(); // 启动连接
			session=connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // 创建Session
			destination=session.createQueue("HelloWorld");  // 创建连接的消息队列
			messageConsumer=session.createConsumer(destination); // 创建消息消费者
			JMSConsumer_Listener jmsConsumer_Listener=new JMSConsumer_Listener();
			messageConsumer.setMessageListener(jmsConsumer_Listener.new Listener());
		} catch (JMSException e) {
			e.printStackTrace();
		} 
		
	}
	
	
	/**
	 * 消息监听
	 * @author fendo
	 *
	 */
	public class Listener implements MessageListener{

		@Override
		public void onMessage(Message message) {
				
			try {
				System.out.println("接收到的消息:"+((TextMessage)message).getText());
			} catch (JMSException e) {
				e.printStackTrace();
			}
			
		}
		
	}

}


完整示例:http://download.csdn.net/detail/u011781521/9907601

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值