Dec 5, 2007

MSMQ Primer

Creating Queues and Managing Queues is a breeze with .NET
Queuenames in .NET:

public queues : .\qname
private : .\private$\qname
journal: .\qname\journal$



Create queues using the MessageQueue class and specify if you need to use Journal queues with the message queue. the Journal queues hold the messages after that have been "received" from the main message queue.
The third type of queues are the AdministrationQueues /Acnowledgement queues and we use the Message.RecieveByCorrelationId method or PeekByCorrelationId to receive admin/ack messages from these queues after a message has been received from the main message queue.
the PeekByCorrelationId method takes in the message id of the message in the main message queue.

public class QueueMgmt

{

public static MessageQueue CreateQueue(string path)

{

MessageQueue mq = null;

if (MessageQueue.Exists(path))

{

mq = new MessageQueue(path);

Console.WriteLine("Connected to existing queue " + path);

}

else

{

mq = MessageQueue.Create(path);

Console.WriteLine("Created to new queue " + path);

}

Console.WriteLine("Message Queue format is " + mq.FormatName);

return mq;

}

}

=========================================================

private void btnCreateQueue_Click(object sender, EventArgs e)

{

// Create a public queue and configure it for journaling.

using (MessageQueue mq = QueueMgmt.CreateQueue(@".\DotNet"))

{

mq.Label = "DotNet Message Queue";

mq.UseJournalQueue = true;

} // mq disposed.

// Create a private queue for acknowledgments.

using (MessageQueue mq = QueueMgmt.CreateQueue(@".\Private$\DotNetAdmin"))

{

mq.Label = "DotNet Acknowledge Queue";

} // mq disposed.

}


=======================================
After creating the queues, you can send messages to the queue using mq.Send method, note we can send any XML Serializable types in the message body. Remember to set the mq.Formatter.TargetTypes property with the TYPES that it is supposed to deserialize when receiving them.

Note we are also setting the Administration queue which will receive the acknowledgment messages once they are read from the Queue.

private void btnSendMessage_Click(object sender, EventArgs e)

{

using (MessageQueue mq = new MessageQueue(@".\dotnet"))

{

using (System.Messaging.Message msg = new System.Messaging.Message())

{

msg.Label = "dotnetmessage";

msg.Body = "Message : " + DateTime.Now.ToString();

msg.AdministrationQueue = new MessageQueue(@".\private$\dotnetadmin");

msg.AcknowledgeType = AcknowledgeTypes.FullReceive;

mq.Send(msg);

Console.WriteLine("Message sent with ID: " + msg.Id);

}

}

}


==============================================
Once the message is sent it arrives in the public or the private queue where it was sent.
Then while receiving the messages we read the message from the public/private queue, once it has been received a copy is stored in the Journal queue if one has been setup.
Also admin messages are sent to the Admin queue depending on the AcknowledgementTypes setup during the sending of the message.
Note we can get mutiple ack/admin messages for a single message by ORing different ackTypes in the message.AcknowledgeType enumneration.

private void btnReceive_Click(object sender, EventArgs e)

{

Type[] targetTypes = { typeof(string) };

string msgId = string.Empty;

using (MessageQueue mq = new MessageQueue(@".\dotnet"))

{

((XmlMessageFormatter)mq.Formatter).TargetTypes = targetTypes;

using (System.Messaging.Message msg = mq.Receive())

{

Console.WriteLine("Received Message ID {0} : \n\t Body = {1}", msg.Id, msg.Body);

msgId = msg.Id;

}

}

using (MessageQueue mq = new MessageQueue(@".\dotnet\Journal$"))

{

((XmlMessageFormatter)mq.Formatter).TargetTypes = targetTypes;

using (System.Messaging.Message msg = mq.PeekById(msgId))

{

Console.WriteLine("Peeked message from Journal Queue {0}:\n\t Body = {1}", msg.Id, msg.Body);

}

}

using (MessageQueue mq = new MessageQueue(@".\private$\dotnetadmin"))

{

using (System.Messaging.Message msg = mq.PeekByCorrelationId(msgId))

{

Console.WriteLine("Peeked Acknowledgement queue {0} : \n\t Acknowledgement is {1}", msg.Id, msg.Acknowledgment);

}

}

}

kick it on DotNetKicks.com

2 comments:

msqr said...

Do we need to cleanup MessageQueue object created to set Administration Queue?

tillu said...

Yes you do. If you are using the using statement for creating the MessageQueue then C# does this for automatically under the covers by calling dispose on the MessageQueue object before exiting.