Author |
Message
|
mikeco3181 |
Posted: Thu Jul 27, 2006 12:16 pm Post subject: C# Dynamic Reply Queue |
|
|
Novice
Joined: 27 Jul 2006 Posts: 17
|
I've been doing .NET apps for about 4 years now. C# for the past 5 or 6 months. MQ for the past week.
Using sample code I've managed to communicate with a queue putting a message and getting back the same message. I need to figure out how to get the reply, for the message I'm putting, from a dynamic reply queue. Unfortunately the people who implemented MQ here for us have been no help at all and IBM's documentation hasn't either.
I've gone through tons of different code and nothing has helped me.
Anyone care to help?
Some code:
Code: |
using System;
using IBM.WMQ;
using System.Collections;
namespace MQConsole
{
/// <summary>
/// Summary description for MQSample2.
/// </summary>
public class MQSample2
{
const string EXISTING_QUEUE = "NY3CC50A.CICS.REQUEST";
const string MESSAGE = "testing";
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static int Main(string[] args1)
{
MQQueueManager mqQMgr; // MQQueueManager instance
MQQueue mqQueue; // MQQueue instance
string queueName; // Name of queue to use
MQMessage mqMsg; // MQMessage instance
MQPutMessageOptions mqPutMsgOpts; // MQPutMessageOptions instance
MQGetMessageOptions mqGetMsgOpts; // MQGetMessageOptions instance
System.Console.WriteLine( "Sample NMQWRLD start" );
string[] args = new string[3];
args[0] = "NY3CC50A.CICS.REQUEST";
args[1] = "QM";
args[2] = "CHANNEL/TCP/HOST";
///
/// Try to create an MQQueueManager instance
///
try
{
if (args.Length > 2)
{
// queue name, queue manager name, channel definition all provided
// Break down the channel definition,
// which is of the form "channel-name/transport-type/connection-name".
string channelDefinition = args[2];
string channelName = "";
string transportType = "";
string connectionName = "";
char[] separator = {'/'};
string[] parts;
parts = channelDefinition.Split( separator );
if (parts.Length > 0) channelName = parts[0];
if (parts.Length > 1) transportType = parts[1];
if (parts.Length > 2) connectionName = parts[2];
mqQMgr = new MQQueueManager( args[1], channelName, connectionName );
}
else
if (args.Length == 2)
{
// queue name, queue manager name provided
mqQMgr = new MQQueueManager( args[1].Trim() );
}
else
{
// queue name provided - use default queue manager
mqQMgr = new MQQueueManager();
}
}
catch (MQException mqe)
{
// stop if failed
System.Console.WriteLine( "create of MQQueueManager ended with " + mqe.Message );
return( (int)mqe.Reason );
}
///
/// Try to open the queue
///
try
{
// If queue name provided, then use it
// otherwise use the default queue name
if (args.Length > 0)
{
queueName = args[0].Trim();
}
else
{
queueName = EXISTING_QUEUE;
}
// The named queue may be a model queue, which will result in the
// creation of a temporary dynamic queue, which will be destroyed as
// soon as it is closed. Therefore we must ensure that such a queue
// is not automatically closed and re-opened. We do this by setting
// open options which will avoid the need for closure and re-opening.
mqQueue = mqQMgr.AccessQueue( queueName,
MQC.MQOO_OUTPUT | MQC.MQOO_INPUT_SHARED | MQC.MQOO_INQUIRE );
}
catch (MQException mqe)
{
// stop if failed
System.Console.WriteLine( "MQQueueManager::AccessQueue ended with " + mqe.Message );
return( (int)mqe.Reason );
}
///
/// Prepare a message containing the text "Hello world".
///
mqMsg = new MQMessage();
mqMsg.WriteString( MESSAGE );
mqMsg.Format = MQC.MQFMT_STRING;
mqPutMsgOpts = new MQPutMessageOptions();
///
/// Place the message on the queue, using default put message options.
///
try
{
mqQueue.Put( mqMsg, mqPutMsgOpts );
}
catch (MQException mqe)
{
// report the error
System.Console.WriteLine( "MQQueue::Put ended with " + mqe.Message );
}
///
/// Discover the queue manager's name.
///
string name = mqQMgr.Name;
if (name != null)
{
System.Console.WriteLine( "The queue manager name is '{0}'.", name );
}
///
/// Show the name of the queue.
///
name = mqQueue.Name;
if (name != null)
{
System.Console.WriteLine( "Message sent to '{0}'.", name );
}
///
/// Retrieve the data message just sent ("Hello world" expected) from the
/// queue, using default get message options. We will get the message just
/// sent, rather than any other message on the queue, because the "put"
/// will have set the id of the message in the message object, so, as we
/// are using the same message object, the message id acts as a filter
/// which says that we are only interested in a message if it has this
/// particular id.
///
mqGetMsgOpts = new MQGetMessageOptions();
try
{
//mqQueue.Get( mqMsg, mqGetMsgOpts );
mqQueue.Get( mqMsg, mqGetMsgOpts );
// Show the text of the received message.
System.Console.WriteLine( "Message of length {0} bytes received, ", mqMsg.MessageLength );
if (mqMsg.Format.CompareTo(MQC.MQFMT_STRING ) == 0)
{
System.Console.WriteLine( mqMsg.ReadString(mqMsg.MessageLength) );
}
else
{
System.Console.WriteLine( "Non-text message" );
}
}
catch (MQException mqe)
{
// report the error
System.Console.WriteLine( "MQQueue::Get ended with " + mqe.Message );
}
System.Console.WriteLine( "Sample NMQWRLD end" );
System.Console.ReadLine();
return (0);
}
}
}
|
and the result:
Quote: |
Sample NMQWRLD start
The queue manager name is 'CSQ1 '.
Message sent to 'NY3CC50A.CICS.REQUEST '.
Message of length 14 bytes received,
testing
Sample NMQWRLD end
|
|
|
Back to top |
|
 |
jefflowrey |
Posted: Thu Jul 27, 2006 12:24 pm Post subject: Re: C# Dynamic Reply Queue |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
mikeco3181 wrote: |
I need to figure out how to get the reply, for the message I'm putting, from a dynamic reply queue. |
When you send a request message, you specify the "ReplyToQ" (and ReplyToQmgr) on the MQMD. This field tells the application receiving the message where to send the reply.
In the case of a dynamic reply queue, what the sending application needs to do is a) open a model queue to create the dynamic queue and then b) put the name of the dynamic queue into the ReplyToQ field.
http://publib.boulder.ibm.com/infocenter/wmqv6/v6r0/index.jsp?topic=/com.ibm.mq.csqzal.doc/wrkdynq.htm _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
mikeco3181 |
Posted: Thu Jul 27, 2006 12:47 pm Post subject: |
|
|
Novice
Joined: 27 Jul 2006 Posts: 17
|
I added
Code: |
/// Open the model Queue
MQQueue mqGetQueue = mqQMgr.AccessQueue("D3000.REPLY.QUEUE.MODEL",MQC.MQOO_INPUT_SHARED,mqQMgr.Name,"DYNAMIC.REPLY*","");
|
and
Code: |
mqGetQueue.Get( mqMsg, mqGetMsgOpts );
|
results were
Quote: |
Sample NMQWRLD start
The queue manager name is 'CSQ1 '.
Message sent to 'NY3CC50A.CICS.REQUEST '.
MQQueue::Get ended with MQRC_NO_MSG_AVAILABLE
Sample NMQWRLD end
|
|
|
Back to top |
|
 |
vennela |
Posted: Thu Jul 27, 2006 12:51 pm Post subject: |
|
|
 Jedi Knight
Joined: 11 Aug 2002 Posts: 4055 Location: Hyderabad, India
|
Are you waiting enough time to have your messages processes and replied back? |
|
Back to top |
|
 |
mikeco3181 |
Posted: Thu Jul 27, 2006 12:54 pm Post subject: |
|
|
Novice
Joined: 27 Jul 2006 Posts: 17
|
vennela wrote: |
Are you waiting enough time to have your messages processes and replied back? |
I just thought of that right before i read this.
I added the following:
Code: |
mqGetMsgOpts.WaitInterval = 30000;
|
and received the same results. Perhaps I'll try unlimited? |
|
Back to top |
|
 |
jefflowrey |
Posted: Thu Jul 27, 2006 12:59 pm Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
Right. You put the message to one queue, and then you opened a new dynamic queue, and tried to get something.
You got no messages, and this is what we expect because it's a new and empty queue.
You also didn't set ReplyToQ and ReplyToQMgr on the MQMD of the message you Put. So if there is something that is reading the queue you Put To, it doesn't know where to send the reply message. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
mikeco3181 |
Posted: Thu Jul 27, 2006 1:01 pm Post subject: |
|
|
Novice
Joined: 27 Jul 2006 Posts: 17
|
so then I have to create the dynamic reply queue prior to putting the message is what you're saying? |
|
Back to top |
|
 |
jefflowrey |
Posted: Thu Jul 27, 2006 1:34 pm Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
mikeco3181 wrote: |
so then I have to create the dynamic reply queue prior to putting the message is what you're saying? |
If you want the program that is supposed to send you a reply to know where to send that reply, yes...
I just want to make sure you're actually doing a request-reply scenario here. If that's the case, then you need to keep in mind that there are always (or should always!) be two queues and two programs. One program is the requestor, and that's the one you're writing. The other program is the server. The requester needs to open the server's input queue, and put the request. That request needs to contain all the information the server needs in order to send the reply. The requester also needs to open the reply queue - which is the requester input queue.
So it looks like
requester -> put -> Queue1 -> Get -> Server
Server -> put -> Reply Queue -> Get -> requester
In your case, you are using a Dynamic reply queue. So you have to create it first - because you can't control when the Server will want to use it. To create a Dynamic queue, you open it!
So your code should be something like
myQueue1 = qmgr.AccessQueue(server queue name,....);
myQueue2 = qmgr.AccessQueue(model queue name, ....);
myRequest = new MQMessage(...);
....
myRequest.ReplyToQueue = ...
myRequest.ReplyToQmgr = ...
...
myQueue1->Put(...myRequest...)
myReply = new MQMessage(....);
myQueue2->Get(...myReply....); _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
fjb_saper |
Posted: Thu Jul 27, 2006 2:13 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
And remember that persistent messages need to go to a permanent queue. They cannot be put to a dynamic temporary queue. If you try they'll probably end up in the DLQ.
If the requester's queue manager is different from the service's qmgr you want to have a default path each way between the 2.
Enjoy  _________________ MQ & Broker admin |
|
Back to top |
|
 |
mikeco3181 |
Posted: Fri Jul 28, 2006 5:33 am Post subject: |
|
|
Novice
Joined: 27 Jul 2006 Posts: 17
|
so now I've created the dynamic queue prior to the put and the get and I have this
Quote: |
Sample NMQWRLD start
The queue manager name is 'CSQ1'.
Message sent to 'NY3CC50A.CICS.REQUEST'.
Message will be received from 'DYNAMIC.REPLYBF2B49161D44E704'.
MQQueue::Get ended with MQRC_NO_MSG_AVAILABLE
Sample NMQWRLD end
|
|
|
Back to top |
|
 |
jefflowrey |
Posted: Fri Jul 28, 2006 5:37 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
Is anyone reading from 'NY3CC50A.CICS.REQUEST'?
Are you waiting long enough on your Get for the reply to be produced? _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
tleichen |
Posted: Fri Jul 28, 2006 5:44 am Post subject: |
|
|
Yatiri
Joined: 11 Apr 2005 Posts: 663 Location: Center of the USA
|
Does your host routine (presumably a CICS app) have access to the dynamic reply queue name that you chose? Have you checked the logs on that system?  _________________ IBM Certified MQSeries Specialist
IBM Certified MQSeries Developer |
|
Back to top |
|
 |
mikeco3181 |
Posted: Fri Jul 28, 2006 5:48 am Post subject: |
|
|
Novice
Joined: 27 Jul 2006 Posts: 17
|
jefflowrey-
I'm pretty sure that NY3CC50A.CICS.REQUEST is a test queue and not really being used by anyone.
tleichen-
This was the name I was told to use. Problem here is that the guys working with me in house aren't 100% knowledgeable on this system. Log check...I'll see if I can get that done
I talked to one of our MQ guys and he showed me some sort of log, here's part of it
Quote: |
+CSQX500I +MQ CSQXRESP Channel Us.CLIENT started
+CSQX208E +MQ CSQXRESP Error receiving data, 442
channel Us.CLIENT
connection "my IP Address" ("my IP Address")
(queue manager ????)
TRPTYPE=TCP RC=00000461 reason=00000000
+CSQX599E +MQ CSQXRESP Channel Us.CLIENT ended abnormally |
Last edited by mikeco3181 on Fri Jul 28, 2006 6:01 am; edited 1 time in total |
|
Back to top |
|
 |
jefflowrey |
Posted: Fri Jul 28, 2006 5:59 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
So if nobody is reading from that queue, then nobody will be sending you a reply, so there won't be anything to get.
You can run the sample program AMQSECHO against that queue, and it will just bounce a reply back to you. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
mikeco3181 |
Posted: Fri Jul 28, 2006 6:02 am Post subject: |
|
|
Novice
Joined: 27 Jul 2006 Posts: 17
|
jefflowrey wrote: |
So if nobody is reading from that queue, then nobody will be sending you a reply, so there won't be anything to get.
You can run the sample program AMQSECHO against that queue, and it will just bounce a reply back to you. |
maybe I misunderstood what you said
see above ("1 week with MQ") |
|
Back to top |
|
 |
|