IBM MQ我如何知道我已阅读所有主题?

时间:2016-05-16 06:33:34

标签: java jms ibm-mq mq

我有一个动态主题树,每个主题的最后一条消息都是“保留”的。当我订阅主题树(使用JMS / Java / MQLibs)时,由于它是动态的,我订阅了通配符“#”,我不知道我将提前收到哪些主题。所以,

  1. 我如何知道我何时至少阅读了所有可用主题?

  2. 我怎么知道读主题是我订阅之前存在的原始“保留”消息,还是订阅后的更新? (我是否需要针对主题保留MessageID的本地映射?我假设我无法将订阅时的时间戳与消息创建时间进行比较,因为服务器和客户端上的时钟可能不同)。

  3. 我添加了一些示例代码,以表明我正在访问主题而不是队列。

    public class JMSServerSubscriber implements MessageListener { 
    
    public JMSServerSubscriber() throws JMSException { 
        TopicConnection topicCon = JmsTopicConnectionFactory.createTopicConnection(); 
        TopicSession topicSes = topicCon.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); 
        Topic topic = topicSes.createTopic("#"); 
        TopicSubscriber topicSub = topicSes.createSubscriber(topic); 
        topicSub.setMessageListener(this); 
        topicCon.start(); 
    } 
    
        @Override 
        public void onMessage(Message arg0) { 
                BytesMessage bm = (BytesMessage) arg0; 
                try { 
                        String destination = bm.getJMSDestination().toString(); 
                } catch (JMSException e) { 
                        e.printStackTrace(); 
                }  
        } 
    } 
    

3 个答案:

答案 0 :(得分:0)

当没有更多的发布时,consumer.receive()方法将使用MQRC 2033原因代码抛出异常。您可以使用原因代码确认您已阅读所有出版物。

在收到的消息上调用getIntProperty(JmsConstants.JMS_IBM_RETAIN);了解出版物是否保留。

答案 1 :(得分:0)

这是我使用PCF的解决方案。请原谅任何语法错误。

public class TopicChecker implements MessageListener { 

    PCFMessageAgent           agent; 
    PCFMessage                pcfm; 
    Set<String>               allTopics; 
    TopicConnection           topicCon; 
    TopicSession              topicSes; 
    Topic                     topic; 
    TopicSubscriber           topicSub; 
    JmsTopicConnectionFactory jcf; 
    int                       total; 

    public TopicChecker() throws Exception { 
        allTopics = new HashSet<>(); 
        MQEnvironment.hostname = "myMqServer"; 
        MQEnvironment.channel = "MY.CHANNEL"; 
        MQEnvironment.port = 1515; 
        MQQueueManager m = new MQQueueManager("MY.QUEUE.MANAGER"); 
        agent = new PCFMessageAgent(m); 
        pcfm = new PCFMessage(MQConstants.MQCMD_INQUIRE_TOPIC_STATUS); 
        pcfm.addParameter(MQConstants.MQCA_TOPIC_STRING, "MyRoot/#"); 
        PCFMessage[] responses = agent.send(pcfm); 

        for (PCFMessage response: responses) { 
            /* We only publish to leaf nodes, so ignore branches. */
            if (response.getIntParameterValue(MQConstants.MQIACF_RETAINED_PUBLICATION) > 0) { 
            allTopics.add(response.getStringParameterValue(MQConstants.MQCA_TOPIC_STRING)); 
            } 
        } 

        total = allTopics.size(); 
        agent.disconnect(); 

        jcf = ...
        topicCon = jcf.createTopicConnection(); 
        topicSes = topicCon.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); 
        topic = topicSes.createTopic("MyRoot/#"); 
        topicSub = topicSes.createSubscriber(topic); 
        topicSub.setMessageListener(this); 
        topicCon.start(); 
    } 

    @Override 
    public void onMessage(Message m) { 
     try { 
        String topicString = m.getJMSDestination().toString().replaceAll("topic://", ""); 
        allTopics.remove(topicString); 
        System.out.println("Read : " + topicString + " " + allTopics.size() + " of " + total + " remaining."); 
        if (allTopics.size() == 0) System.out.println("---------------------DONE----------------------"); 
        } catch (JMSException e) { 
               e.printStackTrace(); 
        } 
   }


   public static void main(String[] args) throws Exception { 
       TopicChecker tc = new TopicChecker(); 
       while (tc.allTopics.size() != 0); 
   } 
} 

答案 2 :(得分:0)

if(response.getIntParameterValue(MQConstants.MQIACF_RETAINED_PUBLICATION)&gt; 0){             allTopics.add(response.getStringParameterValue(MQConstants.MQCA_TOPIC_STRING));             }

从上面的状态响应中,要阅读主题名称,您应该使用“MQCA_ADMIN_TOPIC_NAME”。