IBM WebSphere MQ Listener Service using C#
I need to write a windows based servcie in C# to listen the reuest queue configured in WebSphere MQ 5.3. Whenever a new message arrives in the queue, the service should pick the message and process the request.
I want to know the best practices of implementing the Listener Service in C#.
Should i create a timer thread to listen the queue for new messages at specific intervals? or Is there any other feasible solution to achieve the same?
Thanks in advance
Re: IBM WebSphere MQ Listener Service using C#
> I want to know the best practices of implementing the[color=blue]
> Listener Service in C#.
>
> Should i create a timer thread to listen the queue for
> new messages at specific intervals? or Is there any
> other feasible solution to achieve the same?[/color]
The principles are the same in all procedural languages. Here's pseudocode
MQCONN
MQOPEN the queue
loop
MQGET from the queue
Process the message
end loop
Alternatively, you can write using XMS for the .NET environment: see
[url]http://www.ibm.com/support/docview.wss?rs=171&uid=swg24011756[/url] This API will
allow you to register a callback function that will be called whenever a
message arrives.
Re: IBM WebSphere MQ Listener Service using C#
What Martin didn't emphasise was that you should specify MQGMO_WAIT on your
MQGET.
You should not create a timer thread and poll the queue.
--
Bob Buxton
"Martin" <marting.x@x.uk.ibm.com> wrote in message
news:edkpfe$1200i$1@news.boulder.ibm.com...[color=blue][color=green]
>> I want to know the best practices of implementing the
>> Listener Service in C#.
>>
>> Should i create a timer thread to listen the queue for
>> new messages at specific intervals? or Is there any
>> other feasible solution to achieve the same?[/color]
>
> The principles are the same in all procedural languages. Here's
> pseudocode
>
> MQCONN
> MQOPEN the queue
> loop
> MQGET from the queue
> Process the message
> end loop
>
> Alternatively, you can write using XMS for the .NET environment: see
> [url]http://www.ibm.com/support/docview.wss?rs=171&uid=swg24011756[/url] This API
> will allow you to register a callback function that will be called
> whenever a message arrives.
>[/color]
Re: IBM WebSphere MQ Listener Service using C#
The Listener service should run all the time to look for new messages in the queue. Messages can arrive at any time. In this scenario, how can we set the wait interval for the get method.?
Once processed, the service should look for other new messages and it should continuously.
I plan to create one timer thread that listens the queue at shorter time intervals and get the messages from the queue. will it be a good solution?
Re: IBM WebSphere MQ Listener Service using C#
> The Listener service should run all the time to look for new messages in[color=blue]
> the queue. Messages can arrive at any time. In this scenario, how can we
> set the wait interval for the get method.?
>
> Once processed, the service should look for other new messages and it
> should continuously.[/color]
This very approach is demonstrated in the C sample program amqsget0.c,
available in a full MQ installation. You can read about this and other
sample programs in the WebSphere MQ Application Programming Guide, available
online. That's a really good manual to read to get beckground information
on the questions you're asking; I recommend working through the first
several chapters from the beginning.
Regards
Martin
Re: IBM WebSphere MQ Listener Service using C#
[email]ganesh.t@tcs.com[/email] wrote:[color=blue]
> The Listener service should run all the time to look for new messages
> in the queue. Messages can arrive at any time. In this scenario, how
> can we set the wait interval for the get method.?
>
> Once processed, the service should look for other new messages and it
> should continuously.
>
> I plan to create one timer thread that listens the queue at shorter
> time intervals and get the messages from the queue. will it be a good
> solution?[/color]
Surely you want something like this pseudo-code:
Set wait interval to unlimited
while (no errors)
{
get message
Process message
}
In WebSphere MQ Classes for .NET the constant which specifies an
unlimited wait interval is:
IBM.WMQ.MQC.MQWI_UNLIMITED
Hope this helps.
Regards,
Phil Willoughby
--
Software Engineer (Development)
IBM Message Service Clients for C/C++
Re: IBM WebSphere MQ Listener Service using C#
Maybe this will help...
This is my implementation of the pump and start / stop handlers in the win32
service
processMessagePump is set to false during service shutdown
I experimented with a MQGetMessageOptions set to WAIT_INFINITE hoping it
would block the thread forever until the message arrived. But it would seem
that internally MQ uses a poll so it did not work quite as intended.
private void MessagePump()
{
while(processMessagePump == true) // loop forever processing
whatever message arrives on the queue
{
try
{
MQMessage mqMessage = new MQMessage();
MQGetMessageOptions mqGetMessageOptions = new
MQGetMessageOptions();
mqGetMessageOptions.Options |= MQC.MQGMO_WAIT; //
wait until a message arrives on the queue
mqGetMessageOptions.Options |= MQC.MQGMO_SYNCPOINT; //
sycnronise the queue in case we have to rollback
mqGetMessageOptions.Options |= MQC.MQOO_FAIL_IF_QUIESCING; //
fail it the queue manager is shutting down
mqGetMessageOptions.WaitInterval =
config.MQSeries.QueryIntervals.WaitTimeout; // max time to wait for
message
// wait until either a message arrives on the queue or the timeout
WaitInterval expires
inboundQueue.Get(mqMessage, mqGetMessageOptions);
// process the queued message
ProcessMessage(mqMessage.ReadString(mqMessage.MessageLength));
}
catch(MQException mqe)
{
if(!(MQC.MQCC_FAILED == mqe.CompletionCode &&
MQC.MQRC_NO_MSG_AVAILABLE == mqe.ReasonCode))
{
// its not a "no message available", which is expected; so some
other (more serious) error occurred,
// assume that its a fatal condition.. log it and exit the
processing loop
break;
}
}
finally
{
}
}
}
shutdownEvent.Set(); // this thread is terminating notify any
waitable objects
}
}
<ganesh.t@tcs.com> wrote in message
news:973638557.1157479388393.JavaMail.wassrvr@ltsgwas009.sby.ibm.com...[color=blue]
>I need to write a windows based servcie in C# to listen the reuest queue
>configured in WebSphere MQ 5.3. Whenever a new message arrives in the
>queue, the service should pick the message and process the request.
>
> I want to know the best practices of implementing the Listener Service in
> C#.
>
> Should i create a timer thread to listen the queue for new messages at
> specific intervals? or Is there any other feasible solution to achieve the
> same?
>
> Thanks in advance[/color]
Re: IBM WebSphere MQ Listener Service using C#
For processing the message forget using a timer. It is a waste of effort,
the MQGet method will block until a timeout or a message arrives.
I did something akin to this... Hope this helps...
This may not be the best way of doing things, i am more than happy to
receive critisisms ...
1) Create an exit condition for the thread processMessagePump
2) Run a message pump in a second thread, spawned from OnStart
3) In the message pump loop forever, blocking on the call to message get or
until a timeout occurs. If the get returns within the timeout
then check if its a no message on queue exception. get returns
immediately if a message is available
4) Loop back and process the next available message
5) On shutdown set the exit condition processMessagePump = false
6) When the message pump loop terminates it sets the manual reset even
shutdownEvent to true, to signal that it has finished processing
7) The shutdown waits until it receives notification that the message pump
has shutdown cleanly via the shutdownEvent or forces the shutdown
after waiting a limited time frame.
OnStart()
{
shutdownEvent = new ManualResetEvent(false); // thread sync for
shutdown
// open queus etc....
// queues are open begin pumping messages in the background
processMessagePump = true;
messagePump = new Thread(new ThreadStart(MessagePump));
messagePump.IsBackground = true;
messagePump.Name = "MessagePumpThread";
messagePump.Start();
// OnStart ends .. SCM is happy
}
public void OnShutdown()
{
int millisecondsTimeout =
config.MQSeries.QueryIntervals.ShutdownWaitTimeout;
processMessagePump = false; //
signal the main thread to terminate the loop
shutdownEvent.WaitOne(millisecondsTimeout, false); // wait until the
main thread has terminated or n/ms has passed
// disconnect the queue manager close the queues
MQSeriesElement mq = config.MQSeries;
MQHelper.CloseQueue(mq.InboundQueue.QManager, mq.InboundQueue.QName,
inboundQMgr, inboundQueue);
MQHelper.CloseQueue( mq.OutboundQueue.QManager,
mq.OutboundQueue.QName, outboundQMgr, outboundQueue);
}
MessagePump()
{
while(processMessagePump == true)
{
try
{
MQMessage mqMessage = new MQMessage();
MQGetMessageOptions mqGetMessageOptions = new
MQGetMessageOptions();
mqGetMessageOptions.Options |= MQC.MQGMO_WAIT; //
wait until a message arrives on the queue
mqGetMessageOptions.Options |= MQC.MQGMO_SYNCPOINT; //
sycnronise the queue in case we have to rollback
mqGetMessageOptions.Options |= MQC.MQOO_FAIL_IF_QUIESCING; //
fail it the queue manager is shutting down
mqGetMessageOptions.WaitInterval =
config.MQSeries.QueryIntervals.WaitTimeout; // max time to wait for
message
// wait until either a message arrives on the queue or the timeout
WaitInterval expires
inboundQueue.Get(mqMessage, mqGetMessageOptions);
// if we are here then a message is waiting processing
ProcessMessage(mqMessage.ReadString(mqMessage.MessageLength))
}
catch(MQException mqe)
{
// we are expecting a NO message available if the "GET" timedout
if(!(MQC.MQCC_FAILED == mqe.CompletionCode &&
MQC.MQRC_NO_MSG_AVAILABLE == mqe.ReasonCode))
{
// its not a "no message available", which is expected; so some
other (more serious) error occurred,
// assume that its a fatal condition.. log it and exit the
processing loop
break;
}
}
shutdownEvent.Set(); // this thread is terminating notify any
waitable objects
}
}
Re: IBM WebSphere MQ Listener Service using C#
Phil Willoughby,
Thanks a lot !!
I have implemented the service based on your pseudo-code and it is running fine. I have written the logic to disconnect the queue manager when stopping the service. But when i try to stop the service, the code (QMNGR.Disconnect()) throws an error. I presume the queue manager cannot be stopped if we set the interval as unlimited.
Can you provide a workaround for this ?.
Thanks again.
Re: IBM WebSphere MQ Listener Service using C#
I have implemented the service to successfully GET messages from a queue, using Phil's code.
Works like a dream!
Is it possible or desireable to have the PUT methods using similar methods in the same Windows Service. Both queues belong to the same problem domain.