Author |
Message
|
tsaibird |
Posted: Fri May 04, 2012 6:41 am Post subject: The way to use MQ .NET classes (newbie question) |
|
|
Newbie
Joined: 04 May 2012 Posts: 6
|
Although I have written a .NET application that can put and get message from MQ, but I still have some questions.
While I'm learning how to use MQ .NET API, the first article I read is "IBM WebSphere MQ with C#: GUI application that is both GET REQUEST/ PUT RESPONSE and PUT REQUEST/ GET RESPONSE" on The Code Project. The URL is: http://www.codeproject.com/Articles/12198/IBM-WebSphere-MQ-with-C-GUI-application-that-is-bo
But the following code never worked:
gmo.MatchOptions = MQC.MQMO_MATCH_CORREL_ID;
I've tried again and again, and again, with every possible combinations of MQC.MQMO_MATCH*, they just didn't work. At last, I write a message filter scheme myself. But I think that's not the way to go. Anyone has a working sample about this?
Another question is: Do I need to install MQ Explorer on my client machine? Is there a way that my application can just use amqmdnet.dll and access remote queue?
Thank you! |
|
Back to top |
|
 |
mqjeff |
Posted: Fri May 04, 2012 6:47 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
|
Back to top |
|
 |
Vitor |
Posted: Fri May 04, 2012 6:52 am Post subject: Re: The way to use MQ .NET classes (newbie question) |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
tsaibird wrote: |
I've tried again and again, and again, with every possible combinations of MQC.MQMO_MATCH*, they just didn't work. |
Define "didn't work" - abended, blew up, caused pink slime to ooze from the computer?
Also a little background about how your system is using ids; are you getting WMQ to generate them? Are you certain the responding system is properly populating the correlation id? Have you examined the actual message you think should have been matched to see if it really has the correlation id you're trying to match?
tsaibird wrote: |
Another question is: Do I need to install MQ Explorer on my client machine? Is there a way that my application can just use amqmdnet.dll and access remote queue? |
The MQExplorer has nothing to do with anything your application may or may not be doing. You can install it or not, using one of the support pacs that fulfill that function or not (and have a smaller footprint) or hang by your ankles from the rafters shouting "I'm Arnold the bat" if you want.
Your application will be unaffected. Your co-workers possibly less so.
Also to nitpick your terminology; in WMQ a remote queue is a queue not hosted by the queue manager your application is connected to, a local queue is a queue hosted by that queue manager. This is true even if you've gone over a network to connect to the queue manager and it's not "local" to your application. That particular object on a queue manager is a QREMOTE.
Like I said, nitpicking but clarity helps in here. We can't see what you're doing. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
bruce2359 |
Posted: Fri May 04, 2012 7:47 am Post subject: |
|
|
 Poobah
Joined: 05 Jan 2008 Posts: 9469 Location: US: west coast, almost. Otherwise, enroute.
|
What reason code = didn't work? _________________ I like deadlines. I like to wave as they pass by.
ב''ה
Lex Orandi, Lex Credendi, Lex Vivendi. As we Worship, So we Believe, So we Live. |
|
Back to top |
|
 |
tsaibird |
Posted: Fri May 04, 2012 1:32 pm Post subject: Re: The way to use MQ .NET classes (newbie question) |
|
|
Newbie
Joined: 04 May 2012 Posts: 6
|
Thank you all for providing help.
I'm sorry that I didn't describe about what "didn't work" is. What I try to say is MQC.MQMO_MATCH_CORREL_ID didn't work because my code can never get correlated response messages. Since English is not my mother tongue, I may not explain it well. So here are my code that put the message:
Code: |
public string PutRequestMessage(string message)
{
try
{
MQMessage requestMessage = new MQMessage();
requestMessage.Persistence = 0;
requestMessage.ReplyToQueueName = mqResponseQueueName;
requestMessage.ReplyToQueueManagerName = mqQueueManagerName;
requestMessage.Format = MQC.MQFMT_STRING;
requestMessage.MessageType = MQC.MQMT_REQUEST;
requestMessage.Report = MQC.MQRO_PASS_CORREL_ID | MQC.MQRO_PASS_MSG_ID;
string msgId = GenerateMQMsgId(); // Call a method to generate msg ID.
Encoding encoding = Encoding.UTF8;
requestMessage.MessageId = encoding.GetBytes(msgId);
requestMessage.CorrelationId = requestMessage.MessageId;
MQPutMessageOptions pmo = new MQPutMessageOptions();
pmo.Options = MQC.MQPMO_SET_IDENTITY_CONTEXT;
requestMessage.WriteString(message);
mqRequestQueue.Put(requestMessage, pmo);
string _msgId = Encoding.UTF8.GetString(requestMessage.MessageId); ;
string correlId = Encoding.UTF8.GetString(requestMessage.CorrelationId);
return _msgId.Replace("\0", "");
}
catch (MQException mqex)
{
throw mqex;
}
finally
{
CloseQueue(mqRequestQueue);
}
} |
Then, the server application will put response messages into the queue. I need to fetch all the correlated response messages that correspond to the original request message. Here are the code to get response message:
Code: |
public virtual byte[] GetResponseMessage(byte[] reqMsgID)
{
MQMessage responseMsg = new MQMessage();
responseMsg.CorrelationId = reqMsgID;
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.Options = MQC.MQGMO_WAIT;
gmo.MatchOptions = MQC.MQMO_MATCH_CORREL_ID // No matter what it is, it never work. I mean it never find the match message.
gmo.WaitInterval = pollingTimeout;
try
{
mqResponseQueue.Get(responseMsg, gmo);
string msgId = Encoding.UTF8.GetString(responseMsg.MessageId);
string crId = Encoding.UTF8.GetString(responseMsg.CorrelationId);
byte[] allData = responseMsg.ReadBytes(responseMsg.DataLength);
return allData;
}
catch (MQException mqex)
{
// Check if it a timeout exception
if (mqex.Message.IndexOf("MQRC_NO_MSG_AVAILABLE") >= 0)
{
string s = "Message queue is empty or timed out.";
throw new Exception(s + "\r\n" + mqex.Message);
}
throw mqex;
}
} |
You can see that I used MQC.MQMO_MATCH_CORREL_ID, but it never find any match. I have traced into the code line by line, to see the MsgId and CorrelationId, I also used MQ Explorer to inspect the underlying queue messages, and I found that the CorrelationId in the response message is not the same as I expect -- it should be the same as the request message ID, right?
I don't understand why the CorrelationId matching mechanism doesn't work. I think there must be some basic concept that I missed.
Currently my workaround is to put a magic ID in the request message body. After sending the request message, I browse the message queue and examine them one by one to see which is the response message I need. |
|
Back to top |
|
 |
Vitor |
Posted: Fri May 04, 2012 3:38 pm Post subject: Re: The way to use MQ .NET classes (newbie question) |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
tsaibird wrote: |
I also used MQ Explorer to inspect the underlying queue messages, and I found that the CorrelationId in the response message is not the same as I expect -- it should be the same as the request message ID, right? |
Yes it should and this is why the match option "didn't work". So you need to tell whoever maintains the server application that sends the response message there's a problem with the way they're setting the correlation id.
tsaibird wrote: |
I don't understand why the CorrelationId matching mechanism doesn't work. I think there must be some basic concept that I missed. |
I don't understand why you don't understand. You've said in this post that the correlation id isn't what you expect it to be. It's therefore not the one your code is trying to match on.
I suspect the concept that you or someone is missing is that nothing in WMQ will set the correlation id on a response. WMQ will either leave it blank or generate a new one. If you want the message id from the request in the correlation of the response someone or something has to put it there. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
tsaibird |
Posted: Fri May 04, 2012 6:44 pm Post subject: Re: The way to use MQ .NET classes (newbie question) |
|
|
Newbie
Joined: 04 May 2012 Posts: 6
|
Thank you for your help. But...in my sample code, I did have already put the message ID to the request message, save it somewhere in an byte array, then use that ID when I need to get the matched response messages. I thought WMQ will match it for me.
Would you or somebody tell me where can I find an working example that shows the correct way to get the matched correlated response message? A little sample code would be great help. |
|
Back to top |
|
 |
rekarm01 |
Posted: Sat May 05, 2012 12:17 pm Post subject: Re: The way to use MQ .NET classes (newbie question) |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 1415
|
tsaibird wrote: |
But the following code never worked:
Code: |
gmo.MatchOptions = MQC.MQMO_MATCH_CORREL_ID; |
|
Maybe that's not where the problem is. What is the actual value of requestMessage.MessageId, after it's put on the request queue? What is the actual value of responseMessage.CorrelationId, after it's put on the response queue? Do they match? What is the actual value of reqMsgID? Does it match the requestMessage.MessageId and responseMessage.CorrelationId?
tsaibird wrote: |
Anyone has a working sample about this? |
There seemed to be a working sample here:
Examine more closely how it handles requestMessage.MessageId and responseMessage.CorrelationId, in both the client and server code.
tsaibird wrote: |
Code: |
string msgId = GenerateMQMsgId(); // Call a method to generate msg ID. |
|
What does GenerateMQMsgId() return? Wouldn't it be easier to let WMQ generate the message id? That is its default behavior. |
|
Back to top |
|
 |
tsaibird |
Posted: Mon May 07, 2012 3:20 am Post subject: Re: The way to use MQ .NET classes (newbie question) |
|
|
Newbie
Joined: 04 May 2012 Posts: 6
|
I will think about what you said and try to examine that sample more closely.
Thank you for your help! |
|
Back to top |
|
 |
Vitor |
Posted: Mon May 07, 2012 5:28 am Post subject: Re: The way to use MQ .NET classes (newbie question) |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
tsaibird wrote: |
I thought WMQ will match it for me. |
It will, but only if that id is set in the responding message. You've already posted that it's not what you expect therefore there's a problem in the responding end and nothing you do in your code will get round that. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
tsaibird |
Posted: Wed May 09, 2012 5:36 pm Post subject: Re: The way to use MQ .NET classes (newbie question) |
|
|
Newbie
Joined: 04 May 2012 Posts: 6
|
Vitor wrote: |
tsaibird wrote: |
I thought WMQ will match it for me. |
It will, but only if that id is set in the responding message. You've already posted that it's not what you expect therefore there's a problem in the responding end and nothing you do in your code will get round that. |
Finally, I got it! It's the response end that didn't set the correlation ID. I thought that MQ or the response end will set it for me...How stupid I am!
(The response end is written by another company)
Thank you very much! |
|
Back to top |
|
 |
bruce2359 |
Posted: Wed May 09, 2012 6:20 pm Post subject: |
|
|
 Poobah
Joined: 05 Jan 2008 Posts: 9469 Location: US: west coast, almost. Otherwise, enroute.
|
Learning is a journey. _________________ I like deadlines. I like to wave as they pass by.
ב''ה
Lex Orandi, Lex Credendi, Lex Vivendi. As we Worship, So we Believe, So we Live. |
|
Back to top |
|
 |
Vitor |
Posted: Thu May 10, 2012 5:16 am Post subject: Re: The way to use MQ .NET classes (newbie question) |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
tsaibird wrote: |
Finally, I got it! It's the response end that didn't set the correlation ID. I thought that MQ or the response end will set it for me...How stupid I am!
(The response end is written by another company)
|
As I said above:
Vitor wrote: |
I suspect the concept that you or someone is missing is that nothing in WMQ will set the correlation id on a response. |
_________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
tsaibird |
Posted: Thu May 10, 2012 5:42 am Post subject: Re: The way to use MQ .NET classes (newbie question) |
|
|
Newbie
Joined: 04 May 2012 Posts: 6
|
Vitor wrote: |
tsaibird wrote: |
Finally, I got it! It's the response end that didn't set the correlation ID. I thought that MQ or the response end will set it for me...How stupid I am!
(The response end is written by another company)
|
As I said above:
Vitor wrote: |
I suspect the concept that you or someone is missing is that nothing in WMQ will set the correlation id on a response. |
|
Yes indeed. Thank you  |
|
Back to top |
|
 |
|