概述
一般的订阅,订阅者必须时刻处于活跃状态,才不会遗漏任何信息;持久性订阅,当订阅者处于非活动状态时,代理会为它们保留信息,下一次连接之后推送给它们。
持久订阅
与一般的定于相比,持久性订阅需要:
- 为Connection指定一个唯一的ClientID
- 在这里,Connection有客户端的含义
- ClientID的变化,将被视为不同的客户端 - 创建Subscriber时,指定一个name
- name的变化,将被视为不同的订阅者
API
javax.jms.Connection
- setClientID():java.lang.String
- 为Connection指定ClientID
javax.jms.Session
- createDurableSubscriber(Topic dest, String name):TopicSubscriber
- 创建持久订阅者,并指定名称 - createDurableSubscriber(Topic dest, String name, String msgSelector, boolean noLocal)
- 创建持久订阅者,并指定名称、消息选择器,设置是否忽略本地的消息
- msgSelector:消息选择器,以类似于SQL的语法,根据消息的属性过滤消息;参考04. 消息选择器。
- noLocal:是否忽略同一个Connection递送的消息(当为Connection指定了ClientID,代理就可以知道消息的生产者是不是来自同一个Connection;同一个客户端的通信一般不需要通过消息队列,就好像把左手的东西递给右手,不需要先把东西放在桌上,右手再去拿一样;所以,设计者认为有必要提供这样一个属性,让消费者自己确认是否忽略来自同一个客户端的消息)
核心代码
对于消息生产者并没有什么特殊的地方,下面是消费者的核心代码:
connection = connectionFactory.createConnection();
connection.setClientID("Client-20160406"); // 为Connection指定ClientID
connection.start(); session = connection.createSession(Boolean.FALSE,
Session.AUTO_ACKNOWLEDGE);
consumer = session.createDurableSubscriber(topic, "subscriber-2016040601"); // 为subscriber指定name consumer.setMessageListener(listener);