Jms 我如何订阅activemq以在消费者处理消息时获得通知

Jms 我如何订阅activemq以在消费者处理消息时获得通知,jms,monitoring,activemq,Jms,Monitoring,Activemq,实际上,我正在寻找ActiveMQ提供的建议或任何其他替代支持,以便在与消费者关联的MessageListener完成消息处理时通知我 MessageDelivered通知似乎会在代理收到消息后立即通知。此外,MessageConsumed advisory声称在消费者收到消息时发出通知 ------------------------更新------------------------------ 请在下面查找代码段: public class SampleListener implement

实际上,我正在寻找ActiveMQ提供的建议或任何其他替代支持,以便在与消费者关联的MessageListener完成消息处理时通知我

MessageDelivered通知似乎会在代理收到消息后立即通知。此外,MessageConsumed advisory声称在消费者收到消息时发出通知

------------------------更新------------------------------

请在下面查找代码段:

public class SampleListener implements MessageListener {

    private Session session;

    public SampleListener(Session session) {
        this.session = session; 
    }

    public void onMessage(Message message) {
        try {
             // do something
             session.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public class SampleConsumer {

    private boolean stopConnection = false;

    public static void main(String[] args) {
        new SampleConsumer().start();
    }

    public void start() {
            ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
            Connection connection;
            try {
                connection = connectionFactory.createConnection();
                connection.start();
                Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
                Destination destination = session.createTopic("test");
                MessageConsumer messageConsumer = session.createConsumer(destination);
                messageConsumer.setMessageListener(new SampleListener(session));

                try {
                    synchronized (this) {
                        while (!stopConnection) {
                            wait();
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    session.close();
                    connection.close();
                }

            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }

    public void stop() {
        synchronized (this) {
            stopConnection = true;
            notify();
        }
    }
}


public class SampleProducer implements MessageListener {

    private boolean messageDelivered;

    @Test
    public void shouldTestSomething() throws JMSException, InterruptedException {
        producerConnection = new ActiveMQConnectionFactory("tcp://localhost:61616").createConnection();
        producerConnection.start();
        Session session = producerConnection.createSession(true, SESSION_TRANSACTED);

        Destination destination = session.createTopic("test");
        MessageConsumer advisoryConsumer = session.createConsumer(AdvisorySupport.getMessageConsumedAdvisoryTopic(destination));
        advisoryConsumer.setMessageListener(this);

        Message message = session.createTextMessage("Hi");
        Destination destination = session.createTopic("test");
        MessageProducer producer = session.createProducer(destination);
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);
        producer.send(message);
        session.commit();

        synchronized (this) {
            while (!messageDelivered) {
                wait();
            }
        }

        session.close();

        // some assertions
    }

    public void onMessage(Message message) {
        // do something

        synchronized (this) {
            messageDelivered = true;
            notify();
        }
    }
}

默认情况下,某些咨询未启用。Se链接:

可以通过向activemq.xml添加policyEntry来启用禁用的通知

将以下内容添加到activemq.xml:

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

(我没有找到任何方法在不使用activemq.xml的情况下启用禁用的咨询)

如果将ack模式设置为Transactived,则会发生什么情况?MessageConsumed advisory仍会提前发生?根据其shouldnt.Aksel的关闭原因,确认模式已被处理。虽然MessageDelivered advisory发生得很早,但我无法通过MessageConsumed advisory获得任何通知。我使用PolicyEntry参数打开MessageConsumed,但仍然没有任何消息排队等待MessageConsumed advisory.im的消息。问题是您认为消息会在早期被使用,还是您没有设法为其启用建议?后者。我确实看到MessageConsumed advisory被登记在管理控制台的Topics部分中,但是这个主题没有发生任何变化,即配置为侦听这个建议的侦听器从未被调用。然而,在侦听MessageDelivered advisory时,通知会在消费者消费完消息之前发生。您正在调用onMessage()中的session.commit()?否则我就猜不到了,需要看一些代码才能更好地回答汉克斯·阿克塞尔的问题。我一直在policyEntry中使用advisoryForConsumed=“true”(我使用外部代理,而不是嵌入式代理)。管理控制台确实显示了此建议的条目,并且它确实反映了建议消息侦听器。但是没有任何建议消息在该建议中排队,因此没有消息到达侦听器。我的直觉是,这与制作人和消费者使用不同的会话和不同的线程有关,但我不明白为什么这会是一个问题。我让你的代码做了一些小改动,我会粘贴它,我想我不会让你高兴的,其中一个变化是使用队列而不是主题:consumer:producer:config:首先,非常感谢您指出它适用于队列,我尝试了它,它也起了作用!幸运的是,我现在意识到我正在构建的应用程序更倾向于处理队列语义,因为在订户注册之前,主题不会缓冲任何消息。这样我的问题就解决了。但我仍然很好奇,为什么MessageConsumed advisory不适用于主题。它是否故意不起作用?或者我遗漏了什么?是否可以使用PAHO或其他JS客户端订阅javascript中的咨询主题
BrokerService broker = BrokerFactory.createBroker("xbean:activemq.xml",true);