How to read messages from queue
The problem is how to read messages without removing them from the queue when NMS (C#) client is used.
Unfortunately ActiveMQ does not expose its administrative interfaces so it is not possible to obtain list of queues, or enumerate messages in the queue without removing them.
But knowledge of how queue server works gives us opportunity to cheat. If we open session with ClientAcknowledge mode then server will wait for clien issued confirmation before deleting message from queue. If we intentionally skip confirming than we can keep reading messages up to some limit.
using(IConnection conn = new ConnectionFactory("tcp://localhost:61616").CreateConnection())
{
conn.Start();
ISession session = conn.CreateSession(AcknowledgementMode.ClientAcknowledge);
IQueue queue = session.GetQueue("aaa");
for(int i=0; i<10; i++)
producer.Send(producer.CreateTextMessage("a test "+i));
List<IMessage> list = new List<IMessage>();
using(IMessageConsumer iterator = session.CreateConsumer(queue)) {
iterator.Listener += delegate(IMessage m) {list.Add(m);};
System.Threading.Thread.Sleep(250);
}
Console.WriteLine("First attempt: {0}", list.Count);
// walk through messages again to make sure we did not remove them first time
list.Clear();
using(IMessageConsumer iterator = session.CreateConsumer(queue)) {
iterator.Listener += delegate(IMessage m) {list.Add(m);};
System.Threading.Thread.Sleep(250);
}
Console.WriteLine("Second attempt: {0}", list.Count);
It is important to open session in ClientAcknowledge and not acknowledge messages to avoid their removal from the queue. Also I wrapped consumer into "using" clause in order to call Dispose which will inform queue server that messages sent to this consumer are free. We want to do it as soon as we are done and not relay on garbage collector which can kick in who knows when.
The sleep for 250ms is to give time to consumer to fulfill its buffer. See my notes about problem here.
The method described is a trick and there is a limit on how many messages you can receive. ActiveMQ will throttle consumer which receives messages but does not confirm their processing. But you hould be fine with showning first hundred or so messages. It would serve displaying purposes.