问题
In a sandbox environment, I'm testing out the IBM MQ. I already have experience with RabbitMq.
With IBM MQ, I lack the possibility to directly consume a message in the queue. This is the case with RabbitMQ (Consume() methods). But with IBM MQ I have to explicitly look in the queue with following code:
var queue = _queueManager.AccessQueue("queueName", MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING);
This is what I know about reading a message from the queue right now. But is there anyone who can help me if there is a way to directly consume a message (event wise, or in other words: realtime consumption. The item in the queue would be the trigger to start reading it.) without calling the above code?
回答1:
You could look at using a message listener of XMS .NET client for consuming messages as and when they arrive in a queue. You need to refer IBM.XMS assembly in your project. You can look at the asynchronous consumer sample Tools\dotnet\samples\cs\xms\simple\wmq\SimpleAsyncConsumer\SimpleAsyncConsumer.cs.
回答2:
If you want to be triggered by a message arrival on a queue, you can configure a PROCESS and set that process up to run based on a trigger message to the queue.
Alternatively, you can look into the MQGMO_WAIT and you can keep a thread blocking while listening for a message on the queue using almost the exact code you have above.
EDIT: So you could set your code up to be called whenever a message arrives on a trigger queue (every), or the first time a message arrives on a trigger queue (first), and your MQ Process would be something like "/path/to/myprog.exe". The parameters passed in would be in the format of an MQTriggerMessage, and include the queue name and a few other details. This would allow for any number of processing tasks assuming you set trigger on every message.
Alternatively, you could open the queue as shared, and multiple tasks can be waiting on a message to arrive on the queue. Using the MQOpenOption.INPUT_SHARED flag.
回答3:
But with IBM MQ I have to explicitly look in the queue with following code:
var queue = _queueManager.AccessQueue("queueName", ...
You need to do a little more reading because AccessQueue only opens the queue. You need to use the Queue's Get method to retrieve the message.
If you want to do it forever (until the queue manager shutdowns) then you can do this:
private void loopForever(MQQueue inQ)
{
bool flag = true;
MQMessage msg = new MQMessage();
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.Options |= MQC.MQGMO_WAIT | MQC.MQGMO_FAIL_IF_QUIESCING;
gmo.WaitInterval = MQC.MQEI_UNLIMITED;
while (flag)
{
try
{
msg = new MQMessage();
inQ.Get(msg, gmo);
System.Console.Out.WriteLine("Message Data: " + msg.ReadString(msg.MessageLength));
}
catch (MQException mqex)
{
System.Console.Out.WriteLine("MQTest61B CC=" + mqex.CompletionCode + " : RC=" + mqex.ReasonCode);
flag = false; // severe error - time to exit
}
catch (System.IO.IOException ioex)
{
System.Console.Out.WriteLine("MQTest61B ioex=" + ioex);
}
}
}
来源:https://stackoverflow.com/questions/43541550/ibm-mq-v8-real-time-consumption-of-a-published-message