获取MessageConsumed

时间:2015-06-26 17:37:31

标签: jms activemq spring-jms

当ActiveMQ客户端使用MQTT消息时,我需要能够接收通知。

activemq.xml中

<destinationPolicy>
    <policyMap>
      <policyEntries>
            <policyEntry topic=">" advisoryForConsumed="true" />
      </policyEntries>
    </policyMap>
</destinationPolicy>

在下面的代码中,我在myTopic上获得了MQTT消息。我没有在processAdvisoryMessage / processAdvisoryBytesMessage中获得咨询消息。

@Component
public class MqttMessageListener {
    @JmsListener(destination = "mytopic")
    public void processMessage(BytesMessage message) {
    }

    @JmsListener(destination = "ActiveMQ.Advisory.MessageConsumed.Topic.>")
    public void processAdvisoryMessage(Message message) {
        System.out.println("processAdvisoryMessage Got a message");
    }

    @JmsListener(destination = "ActiveMQ.Advisory.MessageConsumed.Topic.>")
    public void processAdvisoryBytesMessage(BytesMessage message) {
        System.out.println("processAdvisoryBytesMessageGot a message");
    }
}

我做错了什么?

我也尝试过使用ActiveMQ BrokerFilter:

public class AMQMessageBrokerFilter extends GenericBrokerFilter {
    @Override
    public void acknowledge(ConsumerBrokerExchange consumerExchange, MessageAck ack) throws Exception {
        super.acknowledge(consumerExchange, ack);
    }

@Override
public void postProcessDispatch(MessageDispatch messageDispatch) {
    Message message = messageDispatch.getMessage();
}

@Override
public void messageDelivered(ConnectionContext context, MessageReference messageReference) {
    log.debug("messageDelivered called.");
    super.messageDelivered(context, messageReference);
}

@Override
public void messageConsumed(ConnectionContext context, MessageReference messageReference) {
    log.debug("messageConsumed called.");
    super.messageConsumed(context, messageReference);
}   

在第二种情况下,我无法同时收到消息和发送消费通知的提示。 acknowledge / messageDelivered / messageConsumed都有一个连接上下文,但只有postProcessDispatch有我需要的部分消息(有效负载是JSON)才能发送我的外发消息。我可能很渴望并且使用发送两者都有,但是等到至少它被承认是更安全。

我试过了:

@Override
public void postProcessDispatch(MessageDispatch messageDispatch) {
    super.postProcessDispatch(messageDispatch);
    String topic =  messageDispatch.getDestination().getPhysicalName();
    if( topic == null || topic.equals("delivered") )
        return;

    try {
        ActiveMQTopic responseTopic = new ActiveMQTopic("delivered");
        ActiveMQTextMessage responseMsg = new ActiveMQTextMessage();
        responseMsg.setPersistent(false);
        responseMsg.setResponseRequired(false);
        responseMsg.setProducerId(new ProducerId());
        responseMsg.setText("Delivered msg: "+msg);
        responseMsg.setDestination(responseTopic);
        String messageKey = ":"+rand.nextLong();
        MessageId msgId = new MessageId(messageKey);
        responseMsg.setMessageId(msgId);

        ProducerBrokerExchange producerExchange=new ProducerBrokerExchange();
        ConnectionContext context = getAdminConnectionContext();
        producerExchange.setConnectionContext(context);
        producerExchange.setMutable(true);
        producerExchange.setProducerState(new ProducerState(new ProducerInfo()));
        next.send(producerExchange, responseMsg); 
    } 
    catch (Exception e) {
        log.debug("Exception: "+e);
    }

但是上面似乎导致服务器不稳定。我认为这与使用似乎错误的getAdminConnectionContext有关。

1 个答案:

答案 0 :(得分:0)

我的工厂默认将setPubSubDomain设置为false。这会禁用主题的建议消息的连接。我把它设置为true,事情就开始了。请注意,队列不适用于此集。为了解决这个问题,我创建了两个工厂,并将它们命名为bean。

    @Bean(name="main")
    public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory connectionFactory) {
        DefaultJmsListenerContainerFactory factory =  new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
//        factory.setDestinationResolver(destinationResolver);
//        factory.setPubSubDomain(true);
        factory.setConcurrency("3-10");
        return factory;
    }