一、简介
点对点的消息发送方式主要建立在 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