ActiveMQ

1、ActiveMQ服务器工作模型
      通过ActiveMQ消息服务交换消息。消息生产者将消息发送至消息服务,消息消费者则从消息服务接收这些消息。这些消息传送操作是使用一组实现 ActiveMQ应用编程接口 (API) 的对象来执行的。
      ActiveMQ客户端使用 ConnectionFactory 对象创建一个连接,向消息服务发送消息以及从消息服务接收消息均是通过此连接来进行。Connection 是客户端与消息服务的活动连接。创建连接时,将分配通信资源以及验证客户端。这是一个相当重要的对象,大多数客户端均使用一个连接来进行所有的消息传送。  连接用于创建会话。Session 是一个用于生成和使用消息的单线程上下文。它用于创建发送的生产者和接收消息的消费者,并为所发送的消息定义发送顺序。会话通过大量确认选项或通过事务来支持可靠传送。  客户端使用 MessageProducer 向指定的物理目标(在 API 中表示为目标身份对象)发送消息。生产者可指定一个默认传送模式(持久性消息与非持久性消息)、优先级和有效期值,以控制生产者向物理目标发送的所有消息。
同样,客户端使用 MessageConsumer 对象从指定的物理目标(在 API 中表示为目标对象)接收消息。消费者可使用消息选择器,借助它,消息服务可以只向消费者发送与选择标准匹配的那些消息。  消费者可以支持同步或异步消息接收。异步使用可通过向消费者注册 MessageListener 来实现。当会话线程调用 MessageListener 对象的 onMessage 方法时,客户端将使用消息。

2、ActiveMQ消息传送模型
ActiveMQ 支持两种截然不同的消息传送模型:PTP(即点对点模型)和Pub/Sub(即发布 /订阅模型),分别称作:PTP Domain 和Pub/Sub Domain。

PTP(使用Queue 即队列目标) 消息从一个生产者传送至一个消费者。在此传送模型中,目标是一个队列。消息首先被传送至队列目标,然后根据队列传送策略,从该队列将消息传送至向此队列进行注册的某一个消费者,一次只传送一条消息。可以向队列目标发送消息的生产者的数量没有限制,但每条消息只能发送至、并由一个消费者成功使用。如果没有已经向队列目标注册的消费者,队列将保留它收到的消息,并在某个消费者向该队列进行注册时将消息传送给该消费者。

Pub/Sub(使用 Topic即主题目标) 消息从一个生产者传送至任意数量的消费者。在此传送模型中,目标是一个主题。消息首先被传送至主题目标,然后传送至所有已订阅此主题的活动消费者。可以向主题目标发送消息的生产者的数量没有限制,并且每个消息可以发送至任意数量的订阅消费者。主题目标也支持持久订阅的概念。持久订阅表示消费者已向主题目标进行注册,但在消息传送时此消费者可以处于非活动状态。当此消费者再次处于活动状态时,它将接收此信息。如果没有已经向主题目标注册的消费者,主题不保留其接收到的消息,除非有非活动消费者注册了持久订阅。

3、ActiveMQ消息选择器
ActiveMQ提供了一种机制,使用它,消息服务可根据消息选择器中的标准来执行消息过滤。生产者可在消息中放入应用程序特有的属性,而消费者可使用基于这些属性的选择标准来表明对消息是否感兴趣。这就简化了客户端的工作,并避免了向不需要这些消息的消费者传送消息的开销。然而,它也使得处理选择标准的消息服务增加了一些额外开销。 消息选择器是用于MessageConsumer的过滤器,可以用来过滤传入消息的属性和消息头部分(但不过滤消息体),并确定是否将实际消费该消息。消息选择器是一些字符串,它们基于某种语法,而这种语法是SQL-92的子集。可以将消息选择器作为MessageConsumer 创建的一部分。

4、ActiveMQ消息签收
在不带事务的 Session 中,一条消息何时和如何被签收取决于Session的设置。
1.Session.AUTO_ACKNOWLEDGE
当客户端从 receive 或 onMessage成功返回时,Session 自动签收客户端的这条消息的收条。在AUTO_ACKNOWLEDGE的 Session 中,同步接收 receive是上述三个阶段的一个例外,在这种情况下,收条和签收紧随在处理消息之后发生。
2.Session.CLIENT_ACKNOWLEDGE
    客户端通过调用消息的 acknowledge 方法签收消息。在这种情况下,签收发生在 Session 层面:签收一个已消费的消息会自动地签收这个 Session 所有已消费消息的收条。
3.Session.DUPS_OK_ACKNOWLEDGE
   此选项指示 Session 不必确保对传送消息的签收。它可能引起消息的重复,但是降低了 Session 的开销,所以只有客户端能容忍重复的消息,才可使用(如果ActiveMQ 再次传送同一消息,那么消息头中的JMSRedelivered 将被设置为 true)。客户端成功接收一条消息的标志是这条消息被签收。成功接收一条消息一般包括如下三个阶段:
1.客户端接收消息;
2.客户端处理消息;
3.消息被签收。签收可以由 ActiveMQ发起,也可以由客户端发起,取决于 Session 签收模式的设置。 在带事务的 Session 中,签收自动发生在事务提交时。如果事务回滚,所有已经接收的消息将会被再次传送。

5、ActiveMQ消息传送模式
ActiveMQ 支持两种消息传送模式:PERSISTENT 和 NON_PERSISTENT 两种。
1.PERSISTENT(持久性消息)
        这是 ActiveMQ 的默认传送模式,此模式保证这些消息只被传送一次和成功使用一次。对于这些消息,可靠性是优先考虑的因素。可靠性的另一个重要方面是确保持久性消息传送至目标后,消息服务在向消费者传送它们之前不会丢失这些消息。这意味着在持久性消息传送至目标时,消息服务将其放入持久性数据存储。如果消息服务由于某种原因导致失败,它可以恢复此消息并将此消息传送至相应的消费者。虽然这样增加了消息传送的开销,但却增加了可靠性。
2.NON_PERSISTENT(非持久性消息)
    保证这些消息最多被传送一次。对于这些消息,可靠性并非主要的考虑因素。此模式并不要求持久性的数据存储,也不保证消息服务由于某种原因导致失败后消息不会丢失。
有两种方法指定传送模式:
1.使用 setDeliveryMode 方法,这样所有的消息都采用此传送模式;
2.使用 send 方法为每一条消息设置传送模式。

6、ActiveMQ优先级设置
通常,可以确保将单个会话向目标发送的所有消息按其发送顺序传送至消费者。然而,如果为这些消息分配了不同的优先级,消息传送系统将首先尝试传送优先级较高的消息。
有两种方法设置消息的优先级:
1.使用 setDeliveryMode 方法,这样所有的消息都采用此传送模式;
2.使用 send 方法为每一条消息设置传送模式;
消息优先级从 0-9 十个级别,0-4 是普通消息,5-9 是加急消息。如果不指定优先级,则默认为 4。JMS 不要求严格按照这十个优先级发送消息,但必须保证加急消息要先于普通消息到达。

7、ActiveMQ消息过期设置
允许消息过期 。默认情况下,消息永不会过期。如果消息在特定周期内失去意义,那么可以设置过期时间。
有两种方法设置消息的过期时间,时间单位为毫秒:
1.使用 setTimeToLive 方法为所有的消息设置过期时间;
2.使用 send 方法为每一条消息设置过期时间。
消息过期时间,send 方法中的 timeToLive 值加上发送时刻的 GMT 时间值。如果 timeToLive 值等于零,则 JMSExpiration 被设为零, 表示该消息永不过期。如果发送后,在消息过期时间之后消息还没有被发送到目的地,则该消息被清除。

8、ActiveMQ持久订阅设置
通过为发布者设置 PERSISTENT传送模式,为订阅者时使用持久订阅,这样可以保证 Pub/Sub 程序接收所有发布的消息。
消息订阅分为非持久订阅(non-durable subscription)和持久订阅(durable subscription),非持久订阅只有当客户端处于激活状态,也就是和 ActiveMQ 保持连接状态才能收到发送到某个主题的消息,而当客户端处于离线状态,这个时间段发到主题的消息将会丢失,永远不会收到。持久订阅时,客户端向ActiveMQ 注册一个识别自己身份的 ID,当这个客户端处于离线时,ActiveMQ会为这个 ID 保存所有发送到主题的消息,当客户端再次连接到ActiveMQ 时, 会根据自己的 ID 得到所有当自己处于离线时发送到主题的消息。持久订阅会增加开销,同一时间在持久订阅中只有一个激活的用户。 建立持久订阅的步骤:
1. 为连接设置一个客户 ID;
2. 为订阅的主题指定一个订阅名称;
上述组合必须唯一。


9、ActiveMQ异步发送消息
ActiveMQ支持生产者以同步或异步模式发送消息。使用不同的模式对 send方法的 反应时间有巨大的影响,反映时间是衡量ActiveMQ 吞吐量的重要因素,使用异步发送
可以提高系统的性能。 在默认大多数情况下,AcitveMQ是以异步模式发送消息。例外的情况:在没有使用事务的情况下,生产者以 PERSISTENT传送模式发送消息。在这种情况下,send方法都是同步的,并且一直阻塞直到 ActiveMQ发回确认消息:消息已经存储在持久性数据存储中。这种确认机制保证消息不会丢失,但会造成生产者阻塞从而影响反应时间。
高性能的程序一般都能容忍在故障情况下丢失少量数据。如果编写这样的程序,可以通过使用异步发送来提高吞吐量(甚至在使用PERSISTENT 传送模式的情况下)。

10、ActiveMQ消费者特性
(1)消费者异步分派
在 ActiveMQ4 中,支持 ActiveMQ 以同步或异步模式向消费者分派消息。这样的意义:可以以异步模式向处理消息慢的消费者分配消息;以同步模式向处理消息快的消费
者分配消息。 ActiveMQ默认以同步模式分派消息(setDispatchAsync(false)或TEST.QUEUE?consumer.dispatchAsync=false),这样的设置可以提高性能。但是对于处理消息慢的消费者,需要以异步模式分派。

(2)消费者优先级
在 ActveMQ 分布式环境中,在有消费者存在的情况下,如果更希望ActveMQ 发送消给消费者而不是其他的 ActveMQ 到ActveMQ 的传送,可以如下设置: TEST.QUEUE?consumer.prority=10

(3)独占消费者
ActiveMQ维护队列消息的顺序并顺序把消息分派给消费者。但是如果建立了多个Session 和 MessageConsumer,那么同一时刻多个线程同时从一个队列中接收消息时就并
不能保证处理时有序。 有时候有序处理消息是非常重要的。ActiveMQ4 支持独占的消费。ActiveMQ 挑选一个 MessageConsumer, 并把一个队列中所有消息按顺序分派给它。 如果消费者发生故障,那么 ActiveMQ 将自动故障转移并选择另一个消费者。可以如下设置: TEST.QUEUE?consumer.exclusive=true

11、ActiveMQ消息预取机制

ActiveMQ的目标之一就是高性能的数据传送,所以 ActiveMQ 使用“预取限制”来 控制有多少消息能及时的传送给任何地方的消费者。 一旦预取数量达到限制,那么就不会有消息被分派给这个消费者直到它发回签收消息(用来标识所有的消息已经被处理)。 可以为每个消费者指定消息预取。如果有大量的消息并且希望更高的性能,那么可以为这个消费者增大预取值。如果有少量的消息并且每条消息的处理都要花费很长的时间,那么可以设置预取值为 1,这样同一时间,ActiveMQ 只会为这个消费者分派一条消息。如:TEST.QUEUE?consumer.prefetchSize=10

--------------------------------------------------------------------------------------------------------------------------------------------------------

一、 概述与介绍

    ActiveMQ 是Apache出品,最流行的、功能强大的即时通讯和集成模式的开源服务器。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现。提供客户端支持跨语言和协议,带有易于在充分支持JMS 1.1和1.4使用J2EE企业集成模式和许多先进的功能。

二、 特性

    1、 多种语言和协议编写客户端。语言: Java、C、C++、C#、Ruby、Perl、Python、PHP。应用协议:OpenWire、Stomp REST、WS Notification、XMPP、AMQP

    2、完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务)

    3、对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性

    4、通过了常见J2EE服务器(如 Geronimo、JBoss 4、GlassFish、WebLogic)的测试,其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上

    5、支持多种传送协议:in-VM、TCP、SSL、NIO、UDP、JGroups、JXTA

    6、支持通过JDBC和journal提供高速的消息持久化

    7、从设计上保证了高性能的集群,客户端-服务器,点对点

    8、支持Ajax

    9、支持与Axis的整合

    10、可以很容易得调用内嵌JMS provider,进行测试

三、 安装

    开发环境:

    System:Windows

    JDK:1.6+

    IDE:eclipse

    apache ActiveMQ 5.8

    Email:hoojo_@126.com

    Blog:http://blog.csdn.net/IBM_hoojo

    http://hoojo.cnblogs.com/

    1、 下载ActiveMQ,下载地址:http://www.apache.org/dyn/closer.cgi?path=/activemq/apache-activemq/5.8.0/apache-activemq-5.8.0-bin.zip

    2、 解压apache-activemq-5.8.0.zip即可完成ActiveMQ的安装

    3、 解压后目录结构如下

    image

    +bin (windows下面的bat和unix/linux下面的sh) 启动ActiveMQ的启动服务就在这里

    +conf (activeMQ配置目录,包含最基本的activeMQ配置文件)

    +data (默认是空的)

    +docs (index,replease版本里面没有文档)

    +example (几个例子)

    +lib (activeMQ使用到的lib)

    +webapps (系统管理员控制台代码)

    +webapps-demo(系统示例代码)

    -activemq-all-5.8.0.jar (ActiveMQ的binary)

    -user-guide.html (部署指引)

    -LICENSE.txt

    -NOTICE.txt

    -README.txt

    其他文件就不相信介绍了,搞Java的应该都知道干什么用的。

    你可以进入bin目录,使用activemq.bat双击启动(windows用户可以选择系统位数,如果你是linux的话,就用命令行的发送去启动),如果一切顺利,你就会看见类似下面的信息:

    image

    如果你看到这个,那么恭喜你成功了。如果你启动看到了异常信息:

    Caused by: java.io.IOException: Failed to bind to server socket: tcp://0.0.0.0:61616?maximumConnections=1000&wireformat.maxFrameSize=104857600 due to: java.net.SocketException: Unrecognized Windows Sockets error: 0: JVM_Bind

    那么我告诉你,很不幸,你的端口被占用了。接下来你大概想知道是哪个程序占用了你的端口,并kill掉该进程或服务。或者你要尝试修改ActiveMQ的默认端口61616(ActiveMQ使用的默认端口是61616),在大多数情况下,占用61616端口的是Internet Connection Sharing (ICS) 这个Windows服务,你只需停止它就可以启动ActiveMQ了。

    4、 启动成功就可以访问管理员界面:http://localhost:8161/admin,默认用户名和密码admin/admin。如果你想修改用户名和密码的话,在conf/jetty-realm.properties中修改即可。

    image

    其中在导航菜单中,Queues是队列方式消息。Topics是主题方式消息。Subscribers消息订阅监控查询。Connections可以查看链接数,分别可以查看xmpp、ssl、stomp、openwire、ws和网络链接。Network是网络链接数监控。Send可以发送消息数据。

    5、 运行demo示例,在dos控制台输入activemq.bat xbean:../conf/activemq-demo.xml 即可启动demo示例。官方提供的user-guide.html中的access the web console中是提示输入:activemq.bat console xbean:conf/activemq-demo.xml,我用这种方式不成功。

    当然你还可以用绝对的文件目录方式:activemq.bat xbean:file:D:/mq/conf/activemq-demo.xml

    image

    如果提示conf/activemq-demo.xml没有找到,你可以尝试改变下路径,也就是去掉上面的“..”。通过http://localhost:8161/demo/ 就可以访问示例了。

    image

四、 消息示例

    1、ActiviteMQ消息有3中形式

    JMS 公共
   

    点对点域
   

    发布/订阅域

    ConnectionFactory
   

    QueueConnectionFactory
   

    TopicConnectionFactory

    Connection
   

    QueueConnection
   

    TopicConnection

    Destination
   

    Queue
   

    Topic

    Session
   

    QueueSession
   

    TopicSession

    MessageProducer
   

    QueueSender
   

    TopicPublisher

    MessageConsumer
   

    QueueReceiver
   

    TopicSubscriber

    (1)、点对点方式(point-to-point)

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

    (2)、发布/订阅 方式(publish/subscriber Messaging)

    发布/订阅方式用于多接收客户端的方式.作为发布订阅的方式,可能存在多个接收客户端,并且接收端客户端与发送客户端存在时间上的依赖。一个接收端只能接收他创建以后发送客户端发送的信息。作为subscriber ,在接收消息时有两种方法,destination的receive方法,和实现message listener 接口的onMessage 方法。

    2、ActiviteMQ接收和发送消息基本流程

    image

    发送消息的基本步骤:

    (1)、创建连接使用的工厂类JMS ConnectionFactory

    (2)、使用管理对象JMS ConnectionFactory建立连接Connection,并启动

    (3)、使用连接Connection 建立会话Session

    (4)、使用会话Session和管理对象Destination创建消息生产者MessageSender

    (5)、使用消息生产者MessageSender发送消息

    

    消息接收者从JMS接受消息的步骤

    (1)、创建连接使用的工厂类JMS ConnectionFactory

    (2)、使用管理对象JMS ConnectionFactory建立连接Connection,并启动

    (3)、使用连接Connection 建立会话Session

    (4)、使用会话Session和管理对象Destination创建消息接收者MessageReceiver

    (5)、使用消息接收者MessageReceiver接受消息,需要用setMessageListener将MessageListener接口绑定到MessageReceiver消息接收者必须实现了MessageListener接口,需要定义onMessage事件方法。

五、 代码示例

在代码开始,我们先建一个project,在这个project中添加如下jar包

image

添加完jar包后就可以开始实际的代码工作了。

    1、 使用JMS方式发送接收消息

    消息发送者

    package com.hoo.mq.jms;

    

    import javax.jms.Connection;

    import javax.jms.ConnectionFactory;

    import javax.jms.DeliveryMode;

    import javax.jms.Destination;

    import javax.jms.MessageProducer;

    import javax.jms.Session;

    import javax.jms.TextMessage;

    import org.apache.activemq.ActiveMQConnection;

    import org.apache.activemq.ActiveMQConnectionFactory;

    

    /**

     * <b>function:</b> 消息发送者

     * @author hoojo

     * @createDate 2013-6-19 上午11:26:43

     * @file MessageSender.java

     * @package com.hoo.mq.jms

     * @project ActiveMQ-5.8

     * @blog http://blog.csdn.net/IBM_hoojo

     * @email hoojo_@126.com

     * @version 1.0

     */

    public class MessageSender {

    

        // 发送次数

        public static final int SEND_NUM = 5;

        // tcp 地址

        public static final String BROKER_URL = "tcp://localhost:61616";

        // 目标,在ActiveMQ管理员控制台创建 http://localhost:8161/admin/queues.jsp

        public static final String DESTINATION = "hoo.mq.queue";

       

        /**

         * <b>function:</b> 发送消息

         * @author hoojo

         * @createDate 2013-6-19 下午12:05:42

         * @param session

         * @param producer

         * @throws Exception

         */   

        public static void sendMessage(Session session, MessageProducer producer) throws Exception {

            for (int i = 0; i < SEND_NUM; i++) {

                String message = "发送消息第" + (i + 1) + "条";

                TextMessage text = session.createTextMessage(message);

               

                System.out.println(message);

                producer.send(text);

            }

        }

       

        public static void run() throws Exception {

           

            Connection connection = null;

            Session session = null;

            try {

                // 创建链接工厂

                ConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, BROKER_URL);

                // 通过工厂创建一个连接

                connection = factory.createConnection();

                // 启动连接

                connection.start();

                // 创建一个session会话

                session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);

                // 创建一个消息队列

                Destination destination = session.createQueue(DESTINATION);

                // 创建消息制作者

                MessageProducer producer = session.createProducer(destination);

                // 设置持久化模式

                producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

                sendMessage(session, producer);

                // 提交会话

                session.commit();

               

            } catch (Exception e) {

                throw e;

            } finally {

                // 关闭释放资源

                if (session != null) {

                    session.close();

                }

                if (connection != null) {

                    connection.close();

                }

            }

        }

       

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

            MessageSender.run();

        }

    }

    

    接受者

    package com.hoo.mq.jms;

    

    import javax.jms.Connection;

    import javax.jms.ConnectionFactory;

    import javax.jms.Destination;

    import javax.jms.Message;

    import javax.jms.MessageConsumer;

    import javax.jms.Session;

    import javax.jms.TextMessage;

    import org.apache.activemq.ActiveMQConnection;

    import org.apache.activemq.ActiveMQConnectionFactory;

    

    /**

     * <b>function:</b> 消息接收者

     * @author hoojo

     * @createDate 2013-6-19 下午01:34:27

     * @file MessageReceiver.java

     * @package com.hoo.mq.jms

     * @project ActiveMQ-5.8

     * @blog http://blog.csdn.net/IBM_hoojo

     * @email hoojo_@126.com

     * @version 1.0

     */

    public class MessageReceiver {

    

        // tcp 地址

        public static final String BROKER_URL = "tcp://localhost:61616";

        // 目标,在ActiveMQ管理员控制台创建 http://localhost:8161/admin/queues.jsp

        public static final String DESTINATION = "hoo.mq.queue";

       

       

        public static void run() throws Exception {

           

            Connection connection = null;

            Session session = null;

            try {

                // 创建链接工厂

                ConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, BROKER_URL);

                // 通过工厂创建一个连接

                connection = factory.createConnection();

                // 启动连接

                connection.start();

                // 创建一个session会话

                session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);

                // 创建一个消息队列

                Destination destination = session.createQueue(DESTINATION);

                // 创建消息制作者

                MessageConsumer consumer = session.createConsumer(destination);

               

                while (true) {

                    // 接收数据的时间(等待) 100 ms

                    Message message = consumer.receive(1000 * 100);

                   

                    TextMessage text = (TextMessage) message;

                    if (text != null) {

                        System.out.println("接收:" + text.getText());

                    } else {

                        break;

                    }

                }

               

                // 提交会话

                session.commit();

               

            } catch (Exception e) {

                throw e;

            } finally {

                // 关闭释放资源

                if (session != null) {

                    session.close();

                }

                if (connection != null) {

                    connection.close();

                }

            }

        }

       

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

            MessageReceiver.run();

        }

    }



    2、 Queue队列方式发送点对点消息数据

    发送方

    package com.hoo.mq.queue;

    

    import javax.jms.DeliveryMode;

    import javax.jms.MapMessage;

    import javax.jms.Queue;

    import javax.jms.QueueConnection;

    import javax.jms.QueueConnectionFactory;

    import javax.jms.QueueSession;

    import javax.jms.Session;

    import org.apache.activemq.ActiveMQConnection;

    import org.apache.activemq.ActiveMQConnectionFactory;

    

    /**

     * <b>function:</b> Queue 方式消息发送者

     * @author hoojo

     * @createDate 2013-6-19 下午04:34:36

     * @file QueueSender.java

     * @package com.hoo.mq.queue

     * @project ActiveMQ-5.8

     * @blog http://blog.csdn.net/IBM_hoojo

     * @email hoojo_@126.com

     * @version 1.0

     */

    public class QueueSender {

       

        // 发送次数

        public static final int SEND_NUM = 5;

        // tcp 地址

        public static final String BROKER_URL = "tcp://localhost:61616";

        // 目标,在ActiveMQ管理员控制台创建 http://localhost:8161/admin/queues.jsp

        public static final String DESTINATION = "hoo.mq.queue";

       

        /**

         * <b>function:</b> 发送消息

         * @author hoojo

         * @createDate 2013-6-19 下午12:05:42

         * @param session

         * @param sender

         * @throws Exception

         */   

        public static void sendMessage(QueueSession session, javax.jms.QueueSender sender) throws Exception {

            for (int i = 0; i < SEND_NUM; i++) {

                String message = "发送消息第" + (i + 1) + "条";

               

                MapMessage map = session.createMapMessage();

                map.setString("text", message);

                map.setLong("time", System.currentTimeMillis());

                System.out.println(map);

               

                sender.send(map);

            }

        }

       

        public static void run() throws Exception {

           

            QueueConnection connection = null;

            QueueSession session = null;

            try {

                // 创建链接工厂

                QueueConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, BROKER_URL);

                // 通过工厂创建一个连接

                connection = factory.createQueueConnection();

                // 启动连接

                connection.start();

                // 创建一个session会话

                session = connection.createQueueSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);

                // 创建一个消息队列

                Queue queue = session.createQueue(DESTINATION);

                // 创建消息发送者

                javax.jms.QueueSender sender = session.createSender(queue);

                // 设置持久化模式

                sender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

                sendMessage(session, sender);

                // 提交会话

                session.commit();

               

            } catch (Exception e) {

                throw e;

            } finally {

                // 关闭释放资源

                if (session != null) {

                    session.close();

                }

                if (connection != null) {

                    connection.close();

                }

            }

        }

       

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

            QueueSender.run();

        }

    }

    接收方

    package com.hoo.mq.queue;

    

    import javax.jms.JMSException;

    import javax.jms.MapMessage;

    import javax.jms.Message;

    import javax.jms.MessageListener;

    import javax.jms.Queue;

    import javax.jms.QueueConnection;

    import javax.jms.QueueConnectionFactory;

    import javax.jms.QueueSession;

    import javax.jms.Session;

    import org.apache.activemq.ActiveMQConnection;

    import org.apache.activemq.ActiveMQConnectionFactory;

    

    /**

     * <b>function:</b> 消息接收者; 依赖hawtbuf-1.9.jar

     * @author hoojo

     * @createDate 2013-6-19 下午01:34:27

     * @file MessageReceiver.java

     * @package com.hoo.mq.queue

     * @project ActiveMQ-5.8

     * @blog http://blog.csdn.net/IBM_hoojo

     * @email hoojo_@126.com

     * @version 1.0

     */

    public class QueueReceiver {

    

        // tcp 地址

        public static final String BROKER_URL = "tcp://localhost:61616";

        // 目标,在ActiveMQ管理员控制台创建 http://localhost:8161/admin/queues.jsp

        public static final String TARGET = "hoo.mq.queue";

       

       

        public static void run() throws Exception {

           

            QueueConnection connection = null;

            QueueSession session = null;

            try {

                // 创建链接工厂

                QueueConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, BROKER_URL);

                // 通过工厂创建一个连接

                connection = factory.createQueueConnection();

                // 启动连接

                connection.start();

                // 创建一个session会话

                session = connection.createQueueSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);

                // 创建一个消息队列

                Queue queue = session.createQueue(TARGET);

                // 创建消息制作者

                javax.jms.QueueReceiver receiver = session.createReceiver(queue);

               

                receiver.setMessageListener(new MessageListener() {

                    public void onMessage(Message msg) {

                        if (msg != null) {

                            MapMessage map = (MapMessage) msg;

                            try {

                                System.out.println(map.getLong("time") + "接收#" + map.getString("text"));

                            } catch (JMSException e) {

                                e.printStackTrace();

                            }

                        }

                    }

                });

                // 休眠100ms再关闭

                Thread.sleep(1000 * 100);

               

                // 提交会话

                session.commit();

               

            } catch (Exception e) {

                throw e;

            } finally {

                // 关闭释放资源

                if (session != null) {

                    session.close();

                }

                if (connection != null) {

                    connection.close();

                }

            }

        }

       

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

            QueueReceiver.run();

        }

    }



    3、 Topic主题发布和订阅消息

    消息发送方

    package com.hoo.mq.topic;

    

    import javax.jms.DeliveryMode;

    import javax.jms.MapMessage;

    import javax.jms.Session;

    import javax.jms.Topic;

    import javax.jms.TopicConnection;

    import javax.jms.TopicConnectionFactory;

    import javax.jms.TopicPublisher;

    import javax.jms.TopicSession;

    import org.apache.activemq.ActiveMQConnection;

    import org.apache.activemq.ActiveMQConnectionFactory;

    

    

    /**

     * <b>function:</b> Queue 方式消息发送者

     * @author hoojo

     * @createDate 2013-6-19 下午04:34:36

     * @file QueueSender.java

     * @package com.hoo.mq.topic

     * @project ActiveMQ-5.8

     * @blog http://blog.csdn.net/IBM_hoojo

     * @email hoojo_@126.com

     * @version 1.0

     */

    public class TopicSender {

       

        // 发送次数

        public static final int SEND_NUM = 5;

        // tcp 地址

        public static final String BROKER_URL = "tcp://localhost:61616";

        // 目标,在ActiveMQ管理员控制台创建 http://localhost:8161/admin/queues.jsp

        public static final String DESTINATION = "hoo.mq.topic";

       

        /**

         * <b>function:</b> 发送消息

         * @author hoojo

         * @createDate 2013-6-19 下午12:05:42

         * @param session 会话

         * @param publisher 发布者

         * @throws Exception

         */   

        public static void sendMessage(TopicSession session, TopicPublisher publisher) throws Exception {

            for (int i = 0; i < SEND_NUM; i++) {

                String message = "发送消息第" + (i + 1) + "条";

               

                MapMessage map = session.createMapMessage();

                map.setString("text", message);

                map.setLong("time", System.currentTimeMillis());

                System.out.println(map);

               

                publisher.send(map);

            }

        }

       

        public static void run() throws Exception {

           

            TopicConnection connection = null;

            TopicSession session = null;

            try {

                // 创建链接工厂

                TopicConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, BROKER_URL);

                // 通过工厂创建一个连接

                connection = factory.createTopicConnection();

                // 启动连接

                connection.start();

                // 创建一个session会话

                session = connection.createTopicSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);

                // 创建一个消息队列

                Topic topic = session.createTopic(DESTINATION);

                // 创建消息发送者

                TopicPublisher publisher = session.createPublisher(topic);

                // 设置持久化模式

                publisher.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

                sendMessage(session, publisher);

                // 提交会话

                session.commit();

               

            } catch (Exception e) {

                throw e;

            } finally {

                // 关闭释放资源

                if (session != null) {

                    session.close();

                }

                if (connection != null) {

                    connection.close();

                }

            }

        }

       

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

            TopicSender.run();

        }

    }

    接收方

    package com.hoo.mq.topic;

    

    import javax.jms.JMSException;

    import javax.jms.MapMessage;

    import javax.jms.Message;

    import javax.jms.MessageListener;

    import javax.jms.Session;

    import javax.jms.Topic;

    import javax.jms.TopicConnection;

    import javax.jms.TopicConnectionFactory;

    import javax.jms.TopicSession;

    import javax.jms.TopicSubscriber;

    import org.apache.activemq.ActiveMQConnection;

    import org.apache.activemq.ActiveMQConnectionFactory;

    

    /**

     * <b>function:</b> 消息接收者; 依赖hawtbuf-1.9.jar

     * @author hoojo

     * @createDate 2013-6-19 下午01:34:27

     * @file MessageReceiver.java

     * @package com.hoo.mq.topic

     * @project ActiveMQ-5.8

     * @blog http://blog.csdn.net/IBM_hoojo

     * @email hoojo_@126.com

     * @version 1.0

     */

    public class TopicReceiver {

    

        // tcp 地址

        public static final String BROKER_URL = "tcp://localhost:61616";

        // 目标,在ActiveMQ管理员控制台创建 http://localhost:8161/admin/queues.jsp

        public static final String TARGET = "hoo.mq.topic";

       

       

        public static void run() throws Exception {

           

            TopicConnection connection = null;

            TopicSession session = null;

            try {

                // 创建链接工厂

                TopicConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, BROKER_URL);

                // 通过工厂创建一个连接

                connection = factory.createTopicConnection();

                // 启动连接

                connection.start();

                // 创建一个session会话

                session = connection.createTopicSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);

                // 创建一个消息队列

                Topic topic = session.createTopic(TARGET);

                // 创建消息制作者

                TopicSubscriber subscriber = session.createSubscriber(topic);

               

                subscriber.setMessageListener(new MessageListener() {

                    public void onMessage(Message msg) {

                        if (msg != null) {

                            MapMessage map = (MapMessage) msg;

                            try {

                                System.out.println(map.getLong("time") + "接收#" + map.getString("text"));

                            } catch (JMSException e) {

                                e.printStackTrace();

                            }

                        }

                    }

                });

                // 休眠100ms再关闭

                Thread.sleep(1000 * 100);

               

                // 提交会话

                session.commit();

               

            } catch (Exception e) {

                throw e;

            } finally {

                // 关闭释放资源

                if (session != null) {

                    session.close();

                }

                if (connection != null) {

                    connection.close();

                }

            }

        }

       

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

            TopicReceiver.run();

        }

    }



    4、 整合Spring实现消息发送和接收,在整合之前我们需要添加jar包,需要的jar包如下

    image

    这些jar包可以在D:\apache-activemq-5.8.0\lib这个lib目录中找到,添加完jar包后就开始编码工作。

    消息发送者

    package com.hoo.mq.spring.support;

    

    import java.util.Date;

    import javax.jms.JMSException;

    import javax.jms.MapMessage;

    import javax.jms.Message;

    import javax.jms.Session;

    import org.springframework.context.ApplicationContext;

    import org.springframework.context.support.FileSystemXmlApplicationContext;

    import org.springframework.jms.core.JmsTemplate;

    import org.springframework.jms.core.MessageCreator;

    

    /**

     * <b>function:</b> Spring JMSTemplate 消息发送者

     * @author hoojo

     * @createDate 2013-6-24 下午02:18:48

     * @file Sender.java

     * @package com.hoo.mq.spring.support

     * @project ActiveMQ-5.8

     * @blog http://blog.csdn.net/IBM_hoojo

     * @email hoojo_@126.com

     * @version 1.0

     */

    public class Sender {

    

        public static void main(String[] args) {

            ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:applicationContext-*.xml");

            JmsTemplate jmsTemplate = (JmsTemplate) ctx.getBean("jmsTemplate");

    

            jmsTemplate.send(new MessageCreator() {

                public Message createMessage(Session session) throws JMSException {

                    MapMessage message = session.createMapMessage();

                    message.setString("message", "current system time: " + new Date().getTime());

                   

                    return message;

                }

            });

        }

    }

    消息接收者

    package com.hoo.mq.spring.support;

    

    import java.util.Map;

    import org.springframework.context.ApplicationContext;

    import org.springframework.context.support.FileSystemXmlApplicationContext;

    import org.springframework.jms.core.JmsTemplate;

    

    /**

     * <b>function:</b> Spring JMSTemplate 消息接收者

     * @author hoojo

     * @createDate 2013-6-24 下午02:22:32

     * @file Receiver.java

     * @package com.hoo.mq.spring.support

     * @project ActiveMQ-5.8

     * @blog http://blog.csdn.net/IBM_hoojo

     * @email hoojo_@126.com

     * @version 1.0

     */

    public class Receiver {

    

        @SuppressWarnings("unchecked")

        public static void main(String[] args) {

            ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:applicationContext-*.xml"); 

             

            JmsTemplate jmsTemplate = (JmsTemplate) ctx.getBean("jmsTemplate"); 

            while(true) { 

                Map<String, Object> map =  (Map<String, Object>) jmsTemplate.receiveAndConvert(); 

               

                System.out.println("收到消息:" + map.get("message")); 

            } 

        }

    }

    这里主要是用到了JmsTemplate这个消息模板,这个对象在spring的IoC容器中管理,所以要从spring的容器上下文中获取。下面看看spring的配置文件applicationContext-beans.xml内容:

    <?xml version="1.0" encoding="UTF-8"?>

    <beans xmlns="http://www.springframework.org/schema/beans"

        xmlns:context="http://www.springframework.org/schema/context"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xsi:schemaLocation="http://www.springframework.org/schema/beans

        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

        http://www.springframework.org/schema/context

        http://www.springframework.org/schema/context/spring-context-3.1.xsd">

       

        <!-- 连接池  -->

        <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop"> 

            <property name="connectionFactory"> 

                <bean class="org.apache.activemq.ActiveMQConnectionFactory"> 

                    <property name="brokerURL" value="tcp://localhost:61616" /> 

                </bean> 

            </property> 

        </bean> 

         

        <!-- 连接工厂 -->

        <bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> 

            <property name="brokerURL" value="tcp://localhost:61616" /> 

        </bean> 

       

        <!-- 配置消息目标 -->

        <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"> 

            <!-- 目标,在ActiveMQ管理员控制台创建 http://localhost:8161/admin/queues.jsp -->

            <constructor-arg index="0" value="hoo.mq.queue" /> 

        </bean> 

    

        <!-- 消息模板 -->

        <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> 

            <property name="connectionFactory" ref="activeMQConnectionFactory" /> 

            <property name="defaultDestination" ref="destination" /> 

            <property name="messageConverter"> 

                <bean class="org.springframework.jms.support.converter.SimpleMessageConverter" />

            </property> 

        </bean> 

    </beans>

    这里的整合就比较简单了,如果你是web工程,那你在需要用jms的时候,只需用注入jmsTemplate即可。

--------------------------------------------------------------------------------------------------------------------------------------------------------

ActiveMQ 设计开发(Topic模式)

package com.jshx.cc.topic;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.MapMessage;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.Topic;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.jshx.cc.common.btnpermission.BeanProvider;
import com.jshx.cc.groupChatContent.entity.Tgroupchatcontent;
import com.jshx.cc.groupChatContent.service.TgroupchatcontentService;
import com.jshx.module.admin.entity.User;
import com.jshx.module.admin.service.UserService;

/**
* 即时通信息发送方topic模式
* @author
*
*/
public class ActivemqSender extends HttpServlet{

private static final String user = ActiveMQConnection.DEFAULT_USER;
private static final String password = ActiveMQConnection.DEFAULT_PASSWORD;
private static final String url = "tcp://localhost:61616";
//private static final String topicName = "secondQueue";

@Autowired
private UserService userService;

@Autowired
private TgroupchatcontentService contentService;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response) {
    ActiveMQConnectionFactory connectionFactory;
        Connection connection;
        Session session;
        MessageProducer producer;
        connectionFactory = new ActiveMQConnectionFactory(user,password,url);
       
        userService = BeanProvider.getBean("userService");//获取userService对象   
       
        contentService = BeanProvider.getBean("tgroupchatcontentService");
        try {
            String chatcontent = request.getParameter("chatContent"); // 聊天内容
            String senderid = request.getParameter("senderId"); // 发送人ID 
            String topicName = request.getParameter("topicName");  // 群组ID
            String loginUserId = senderid; // 当前登录人ID
           
            connection = connectionFactory.createConnection();
            connection.start();
            session = connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE); // 设置自动接收消息
            Topic topic = session.createTopic(topicName);
            producer = session.createProducer(topic);
            producer.setDeliveryMode(DeliveryMode.PERSISTENT);// 设置持久化
           
            User user = userService.findUserById(loginUserId);
            SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            String date = sf.format(new Date());
           
            MapMessage message = session.createMapMessage();
            String chatcontent1 = user.getDisplayName() + "&nbsp;&nbsp;" + date + "<br>" + chatcontent + "<br>";
            message.setStringProperty("chatcontent", chatcontent1);
            message.setStringProperty("senderid", senderid);
            message.setStringProperty("groupid", topicName);
            message.setStringProperty("loginUserId", loginUserId);
           
            if(user != null){
            message.setStringProperty("LoginUserName", user.getDisplayName());//保存发送人的姓名
            message.setStringProperty("LoginId", user.getLoginId());//保存发送人的登录名
            }
           
            // 发送消息到目的地方
            Thread.sleep(1000);
            producer.send(message);
            System.out.println(user.getDisplayName()+"--发送消息的内容是");
            System.out.println(chatcontent);
           
            // 消息入库
            Tgroupchatcontent tgroupchat = new Tgroupchatcontent();
            tgroupchat.setChatcontent(chatcontent);
            tgroupchat.setSenderid(senderid);
            tgroupchat.setGroupid(topicName);
            tgroupchat.setCreateTime(new Date());
            tgroupchat.setUpdateTime(new Date());
            tgroupchat.setCreateUserID(loginUserId);
            tgroupchat.setUpdateUserID(loginUserId);
            tgroupchat.setDelFlag(0);
            contentService.save(tgroupchat);
           
            session.commit();
            session.close();
            connection.close();
           
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
   
    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
        processRequest(request, response); 
    }  
 
    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
        processRequest(request, response); 
    }
}

package com.jshx.cc.topic;

/**
* 即时通信消息接受方topic模式
* @author
*/
import java.io.IOException;
import java.io.PrintWriter;

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.Topic;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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

public class ActivemqReceiver extends HttpServlet{

private static final String user = ActiveMQConnection.DEFAULT_USER;
private static final String password = ActiveMQConnection.DEFAULT_PASSWORD;
private static final String url = "tcp://localhost:61616";
// private static final String topicName = "secondQueue"; // 先写死,当多个群组队列出现 需要修改

protected void processResponse(HttpServletRequest request, HttpServletResponse response) {

// String loginUserId = request.getParameter("sendUserId"); // 当前登录用户ID
String topicName = request.getParameter("topicName");  // 群组ID
String senderId = request.getParameter("senderId"); // 发送人ID
String clientID = topicName + senderId;
ActiveMQConnectionFactory connectionFactory;
        Connection connection = null;
        Session session = null;
        MessageConsumer consumer;
        connectionFactory = new ActiveMQConnectionFactory(user,password,url);
        try {
        final PrintWriter out = response.getWriter();
        response.setContentType("text/html;charset=UTF-8");
        response.setContentType("text/html"); 
            response.setHeader("Cache-Control", "no-store"); 
            response.setHeader("Pragma", "no-cache"); 
            response.setDateHeader("Expires", 0);
            connection = connectionFactory.createConnection();
            connection.setClientID(clientID); //持久订阅需要设置
            connection.start();
            session = connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE);
            Topic topic = session.createTopic(topicName);
            consumer = session.createDurableSubscriber(topic,clientID);
            consumer.setMessageListener(new MessageListener(){
public void onMessage(Message msg){
if(msg != null){
MapMessage message = (MapMessage)msg;
try{
System.out.println("---收到消息--->"+message.getStringProperty("chatcontent"));
out.write(message.getStringProperty("chatcontent"));
}catch(JMSException e){
e.printStackTrace();
}
}
}
});
            // 休眠5秒
            Thread.sleep(1000 * 1);
            // 提交会话
            session.commit();
            System.out.println("结束.....");
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
try {
            if (session != null) {
                session.close();
            }
            if (connection != null) {
                connection.close();
            }
} catch (JMSException e) {
e.printStackTrace();
}
}
    }

@Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
processResponse(request, response); 
    }  
 
    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    processResponse(request, response); 
    }
}

--------------------

ActiveMQ 设计开发(Queue模式)

package com.jshx.cc.queues;

/**
* 即时通信息发送方queue模式
* @author
*/
import java.io.IOException;
import java.util.Date;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.MapMessage;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.jshx.cc.common.btnpermission.BeanProvider;
import com.jshx.cc.instantMessage.entity.TinstantMessage;
import com.jshx.cc.instantMessage.service.TinstantMessageService;
import com.jshx.module.admin.entity.User;
import com.jshx.module.admin.service.UserService;

public class ActivemqSender extends HttpServlet{

private static final String user = ActiveMQConnection.DEFAULT_USER;
private static final String password = ActiveMQConnection.DEFAULT_PASSWORD;
private static final String url = ActiveMQConnection.DEFAULT_BROKER_URL;
private static final String queueName = "firstQueue";

@Autowired
private UserService userService;

@Autowired
private TinstantMessageService messageService;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response) {
        Connection connection = null;
        Session session = null;
        Queue queue;
        MessageProducer producer;
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user,password,url);
       
        userService = BeanProvider.getBean("userService");//获取userService对象
       
        messageService = BeanProvider.getBean("tinstantMessageService");
        try {
            String sendContent = request.getParameter("chatContent"); // 发送内容
            String loginUserId = request.getParameter("sendUserId"); // 当前登录用户ID
            String receivcerId = request.getParameter("recevicer"); // 接受消息方ID
            // 构造从工厂得到连接对象
            connection = connectionFactory.createConnection();
            connection.start();
            // 获取操作连接
            session = connection.createSession(Boolean.TRUE,Session.SESSION_TRANSACTED); // modify by hhc 修改事务控制 优化性能
            queue = session.createQueue(queueName);
            producer = session.createProducer(queue);
            producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);// 设置非持久化,设置异步消息发送优化性能 modify by hhc
            // 构造消息,此处写死
            MapMessage message = session.createMapMessage();
            message.setStringProperty("content", sendContent);
            message.setStringProperty("receivcerId", receivcerId);
            message.setStringProperty("loginUserId", loginUserId);
            User user = userService.findUserById(loginUserId);
            if(user != null){
            message.setStringProperty("LoginUserName", user.getDisplayName());//保存发送人的姓名
            message.setStringProperty("LoginId", user.getLoginId());//保存发送人的登录名
            }
            // 发送消息到目的地
            Thread.sleep(1000);
            producer.send(message);
            System.out.println(user.getDisplayName()+"--发送的消息是--" + sendContent);
            // 消息入库
            TinstantMessage tMessage = new TinstantMessage();
            tMessage.setSenderID(loginUserId);
            tMessage.setReceiverID(receivcerId);
            tMessage.setContent(sendContent);
            tMessage.setDelFlag(0);
            tMessage.setCreateTime(new Date());
            tMessage.setUpdateTime(new Date());
            tMessage.setCreateUserID(loginUserId);
            tMessage.setUpdateUserID(loginUserId);
            messageService.save(tMessage);
            session.commit();
           
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
            if (null != session){
            session.close();
        }
                if (null != connection){
                connection.close();
                }
            } catch (Exception e) {
            e.printStackTrace();
            }
        }
    }
   
    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
        processRequest(request, response); 
    }  
 
    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
        processRequest(request, response); 
    }
}
package com.jshx.cc.queues;

/**
* 即时通信消息接受方queue模式
* @author
*/
import java.io.IOException;
import java.io.PrintWriter;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.Session;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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

public class ActivemqReceiver extends HttpServlet{

private static final String user = ActiveMQConnection.DEFAULT_USER;
private static final String password = ActiveMQConnection.DEFAULT_PASSWORD;
private static final String url = ActiveMQConnection.DEFAULT_BROKER_URL;
private static final String queueName = "firstQueue";

protected void processResponse(HttpServletRequest request, HttpServletResponse response) {
String loginUserId = request.getParameter("sendUserId"); // 当前登录用户ID
String receivcerId = request.getParameter("recevicer"); // 接受消息方ID
        Connection connection = null;
        final Session session;
        Queue queue;
        MessageConsumer consumer;
       
        // 内嵌broker 超快回应消息 优化性能
        /*BrokerService broker = new BrokerService();
        broker.setBrokerName("service");
        broker.setPersistent(false);
        try {
broker.addConnector("tcp://localhost:61616");
broker.start();
} catch (Exception e2) {
e2.printStackTrace();
}*/

// ConnectionFactory :连接工厂,创建JMS连接
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user,password,url);
        try {
        final PrintWriter out = response.getWriter();
        response.setContentType("text/html;charset=UTF-8");
        response.setContentType("text/html"); 
            response.setHeader("Cache-Control", "no-store"); 
            response.setHeader("Pragma", "no-cache"); 
            response.setDateHeader("Expires", 0);
        // 构造从工厂得到连接对象
            connection = connectionFactory.createConnection();
            connection.start();
            // 获取操作连接
            session = connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE);
            queue = session.createQueue(queueName);
            consumer = session.createConsumer(queue,"receivcerId="+"'"+receivcerId+"'"+" and loginUserId="+"'"+loginUserId+"'"); // 使用同一个队列需要添加过滤条件
            consumer.setMessageListener(new MessageListener(){
public void onMessage(Message msg){
if(msg != null){
MapMessage message = (MapMessage)msg;
try{
System.out.println("---收到消息--->"+message.getStringProperty("content"));
out.println(message.getStringProperty("content"));
session.commit();
}catch(JMSException e){
e.printStackTrace();
}finally{
if (null != session){
            try {
session.close();
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
        }
}
}
}
});
            Thread.sleep(1000); //休眠1秒
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        try {
        if (null != connection){
connection.close();
                }
                } catch (JMSException e) {
e.printStackTrace();
}
            }
        }

@Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
processResponse(request, response); 
    }  
 
    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    processResponse(request, response); 
    }
}

package com.jshx.cc.queues;

/**
* 即时通信查询不消费(页面消息提醒类)
* @author
*/
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MapMessage;
import javax.jms.MessageConsumer;
import javax.jms.QueueBrowser;
import javax.jms.Session;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

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

public class ActivemqQuery extends HttpServlet{

private static final String user = ActiveMQConnection.DEFAULT_USER;
private static final String password = ActiveMQConnection.DEFAULT_PASSWORD;
private static final String url = ActiveMQConnection.DEFAULT_BROKER_URL;
private static final String queueName = "firstQueue";

@SuppressWarnings("unchecked")
protected void processResponse(HttpServletRequest request, HttpServletResponse response) {

String receivcerId = request.getParameter("recevicer"); // 接受消息方ID
        // ConnectionFactory :连接工厂,创建JMS连接
        ConnectionFactory connectionFactory;
        // Connection :JMS 客户端到JMS Provider 的连接
        Connection connection = null;
        // Session: 一个发送或接收消息的线程
        final Session session;
        // Destination :消息的目的地;消息发送给谁.
        Destination destination;
        // 消费者,消息接收者
        MessageConsumer consumer;
        //查询消息
        QueueBrowser queueBrowser;
       
        connectionFactory = new ActiveMQConnectionFactory(user,password,url);
       
        try {
        final PrintWriter out = response.getWriter();
        response.setContentType("text/html;charset=UTF-8");
        response.setContentType("text/html"); 
            response.setHeader("Cache-Control", "no-store"); 
            response.setHeader("Pragma", "no-cache"); 
            response.setDateHeader("Expires", 0);
        // 构造从工厂得到连接对象
            connection = connectionFactory.createConnection();
            // 启动
            connection.start();
            // 获取操作连接
            session = connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE);
            // 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置
            destination = session.createQueue(queueName);
            //此queueBrowser可以查看队列中的消息,但不会消费掉。
            queueBrowser = session.createBrowser(session.createQueue(queueName),"receivcerId='"+receivcerId+"'");
            Enumeration<?> enumeration = queueBrowser.getEnumeration();
            JSONArray jsonArr = new JSONArray();
            while (enumeration.hasMoreElements()) {
            MapMessage message = (MapMessage) enumeration.nextElement();
            if(message != null){
            JSONObject json = new JSONObject();
            json.put("content", message.getStringProperty("content"));
            json.put("receivcerId", message.getStringProperty("receivcerId"));
            json.put("loginUserId", message.getStringProperty("loginUserId"));
            json.put("LoginUserName", message.getStringProperty("LoginUserName"));
            json.put("LoginId", message.getStringProperty("LoginId"));
            jsonArr.add(json);
            System.out.println("存在接收人是当前登录人的消息-->" + message.getStringProperty("content"));
            break;
            }
           
            }
            if(jsonArr.size() > 0){
            System.out.println("消息查询结束...正在返回结果到页面.......");
            out.write(jsonArr.toString());
            }else{
            out.write("");
            }
           
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != connection)
                    connection.close();
            } catch (Throwable ignore) {
            }
        }
    }

@Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
processResponse(request, response); 
    }  
 
    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    processResponse(request, response); 
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值