Tuesday, November 22, 2011

An introduction to Microsoft Message Queuing–Part 2

In the previous post, we explored very basic concepts of MSMQ. We used non-transactional queue to send and receive a message. In this post we will try to dive more into Message Queuing Queues.

Simply, queues are logical containers that Message Queuing uses to store and later forward messages, providing the bases for the loosely coupled aspects of Message Queuing. Queues can be created by applications and by Message Queuing. Queues created by applications or by users in an MMC snap-in are referred to as application queues. Queues created by Message Queuing are referred to as system-generated queues (we will talk about system- generated queues in another post).

Depending on the service provided by the queue, application queues can be public or private, and they can be transactional or nontransactional.

Application queues can play any of the following roles:

  • Destination queues : any queue used to send/receive messages between applications.
  • Administration queues : used for acknowledgment messages returned by Message Queuing or connector applications.
  • Response queues : used by receiving applications to return response messages to the sending application.
  • Report queues : used to store report messages returned by Message Queuing.
Destination Queues

Destination queues are any queue used to send/receive messages between applications. The sending application on computer 1 sends the messages to the queue and the receiving application on computer 2 reads the messages from the queue. Typically, destination queues are located on the same computer as the receiving application in order to minimize network traffic.

Public Versus Private Queues The decision to use public or private destination queues depends primarily on whether you want other applications to be able to locate the queues or not. Message Queuing registers private queues locally by storing a description of each queue in a separate file in the local queue storage (LQS) folder on the local computer (the default Lqs folder is %windir%\System32\MSMQ\Storage\Lqs). Also a description of each public queue created on the local computer is also stored locally in a separate file in the Lqs folder.

Adv. of Public Queues:

  • Registered in the directory service, so it can be located by other Message Queuing applications.
  • Persistent and its registration information can be backed up.

Adv. of Private Queues:

  • Requires minimal directory service overhead(faster to create, no latency, and no replication)
  • Can be created and deleted when the directory service is not working
  • Can be accessed directly by name without query the directory service.

Div. of Private Queues:

  • It is registered on local computer, so it is properties cannot be obtained by Message Queuing applications running on remote computers. Private queues can be exposed to other applications by making the location of the private queue known to the applications. To distribute the location of a private queue, an application can send the format name of the private queue as the response queue property of a message.

Transactional Versus Nontransactional Queues The decision to use transactional or nontransactional queues is based on whether the applications accessing the queue will be sending and receiving messages within the context of a transaction. So, what is a transaction ? a transaction is to execute a multiple-steps process such that either all or none of the steps will complete. In reality, transactions are handled by rolling back any steps that have already occurred if the entire transaction is not completed successfully.

When sending messages, only transactional queues can accept messages sent in the context of a transaction. These messages are also referred to as transactional messages. In a similar way, nontransactional queues can only accept messages sent outside the context of a transaction. Note that only transactional messages are delivered with exactly-once-delivery (EOD) guarantees.

When receiving messages, only local transactional queues can be accessed within the context of a transaction. The transactional queue must be local to the receiving application. On the other hand, nontransactional queues can be accessed within or outside of a transaction. Also, transactional queues, local or remote, can be accessed outside of a transaction (because we ask it to do less than what it can do).

If you just want to be able to recover lost messages, don’t use transactional queues. You can set the Recoverable property of a every message you sent. Or you can sent the queue property DefaultPropertiesToSend.Recoverable to true.

Creating a Transactional Queue
  • Through the snap in : just check the check-box Transactional below the queue name textbox.
  • Programmatically : just like privateQueue = MessageQueue.Create(".\\Private$\\privateQueue", true);

MessageQueue have a property called Transactional that you can check to ensure that the queue is transactional

MSMQ supports two types of transactions: Internal and External.

Internal Transactions

Class MessageQueueTransaction can be used to Begin(), Commit(), Abort() the transaction. It also can be passed through Send() and Receive() methods to that operation falls under a transaction. The class also exposes a Status property to give the transaction status. Transaction status can be one of:

  • Initialized : The transaction has been initialized but not yet started.
  • Pending : The transaction has been began but not committed or aborted yet.
  • Committed : The transaction has been committed.
  • Aborted : The transaction has been aborted.

Transaction Types when sending or receiving using MessageQueue class through transactional queues, you could pass one of the values in MessageQueueTransactionType enumeration. This specifies how you would like to interact with the queue. These values are:

  • Single : each queue operation will be doine in a separate internal transaction.
  • None : enable you to receive a message from a transactional queue, but outside a transaction. It also enables us to send a transactional message to a non-transactional queue.
  • Automatic : used with external transactions to direct the send or receive operations to use an already existing transaction context.

Now lets compile these pieces into one example to get sense of what internal transactional queues means.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Messaging;

namespace MSMQ_Demo3
{
class Program
{
static void Main(string[] args)
{
MessageQueueTransaction mqTran = new MessageQueueTransaction();
MessageQueue queueA = MessageQueue.Create(".\\Private$\\TranQueueA", true);
MessageQueue queueB = MessageQueue.Create(".\\Private$\\TranQueueB", true);
mqTran.Begin();
try
{
queueA.Send("Message A", "Label A", mqTran );
queueB.Send("Message B", "Label B", mqTran );
mqTran.Commit();
}
catch(Exception ex)
{
mqTran.Abort();
Console.WriteLine(ex.Message);
}

MessageQueue queueC = new MessageQueue(".\\Private$\\TranQueueA");
MessageQueue queueD = new MessageQueue(".\\Private$\\TranQueueB");
string strMsg = "";
mqTran.Begin();
try
{
Message msg = queueC.Receive(mqTran);
msg.Formatter = new XmlMessageFormatter(new Type[1] { typeof(string) });
strMsg = msg.Body.ToString();
msg = queueD.Receive(mqTran);
msg.Formatter = new XmlMessageFormatter(new Type[1] { typeof(string) });
strMsg += " \n ";
strMsg += msg.Body.ToString();
Console.WriteLine(strMsg);
mqTran.Commit();
}
catch (Exception ex)
{
mqTran.Abort();
Console.WriteLine(ex.Message);
}
Console.WriteLine();
}

}
}



In this example we created two transactional queues, send two messages to them. Then we received these messages. Both the sending and receiving done in a transaction that commits only after the success of all operations. If any errors happened, we abort the whole transaction and rollback all operations done in it.

In future posts we will talk more about MSQM details.

Thursday, November 17, 2011

An introduction to Microsoft Message Queuing

What is MSMQ ? Message Queuing (also known as MSMQ) is a messaging infrastructure and a development tool for creating distributed messaging applications for Microsoft Windows operating systems. Applications developed for Message Queuing send messages to queues, which are temporary storage locations, from which messages can proceed to their final destination as conditions permit.

Installing MSMQ The procedures to install MSMQ on Windows Server 2008, Winows Server 2008 R2, Windows 7, Windows Vista, Windows XP, and Windows Server 2003 are available here

Basic Messaging

MSMQ1

The image shows the basic messaging scenario. You have two applications: a sending application and a receiving application. A sending application prepares a message and puts it into a queue. A message can be any piece of information that the receiving application understands. The receiving application receives the message from the queue and processes it. One thing to note here is that the sender and the receiver are not tightly coupled and they can work without the other application being online.

Messaging in .Net To build a messaging application we need to create at least three components: queue, application to send messages, and another application to receive these messages.

Types of queues The basic types of MSMQ queues are: private and public. Public queues are those that are published in the active directory. So, applications running on different servers throughout the network can find and use public queues through the active directory. Private queues on the other hand are available locally on a particular machine and are not published in the active directory.

Creating a Queue Queues can be created either programmatically or through the computer management snap-in (if you installed MSMQ on your machine).

  • Programmatically The System.Messaging.MessageQueue class provides all the necessary functionality to work with and manipulate MSMQ queues. It is like a wrapper around message queuing. MessageQueue.Create(path) creates a non-transactional message queue at the specified path (we will talk about transactional and non-transactional queues later). For public queues, path is MachineName\QueueName. For private queues, MachineName\Private$\QueueName. You can use "." for the local computer. Code should look like:
MessageQueue privateQueue = MessageQueue.Create(".\\Private$\\privateQueue"); 




  • Through the computer management snap-in Open the computer management snap-in (right click computer, then manage). Navigate to Services and Applications, then Message Queuing. Right click on Private Queues –> New –> Private Queue. Or right click on public Queues –> New –> Public Queue.



MMC



Sending a message Use Send() method of your previously created MessageQueue object like so





privateQueue.Send("Message Body (could be any managed object)", "Message Label");



Receiving a message There are two types of operations with respect to reading a message fom the Queue: Peeking and Receiving. When we receive a message from the queue, the message is removed from the queue. Peeking is similar to Receiving but here the message is not removed from the queue. Code could look like





MessageQueue anotherPrivateQueue = new MessageQueue(".\\Private$\\privateQueue");


System.Messaging.Message msg = anotherPrivateQueue.Receive();



Additional Considerations before writing the first complete messaging application




  • You have to check if there is already a Message Queuing queue with the same name before creating your new queue. Use MessageQueue.Exists(path) to check for queue existence.


  • When receiving a message and before accessing its body, you have to set the Formatter property of the Message object. There is a lot of built-in formatters. For now, we can use XMLFormatter.



Now, let’s get things together into a “Hello, World” example. Open Visual Studio, New project, Windows forms. All reference to System.Messaging namespace. Then edit your code to look like so:





using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Messaging;

namespace MSMQ_Demo
{
class Program
{
static void Main(string[] args)
{
try
{
MessageQueue privateQueue;
if (!MessageQueue.Exists(".\\Private$\\privateQueue"))
privateQueue = MessageQueue.Create(".\\Private$\\privateQueue");
else
privateQueue = new MessageQueue(".\\Private$\\privateQueue");

privateQueue.Send("Hello, World !", "Message Label");
MessageQueue anotherPrivateQueue = new MessageQueue(".\\Private$\\privateQueue");
System.Messaging.Message msg = anotherPrivateQueue.Receive();
msg.Formatter = new System.Messaging.XmlMessageFormatter(new Type[1] { typeof(string) });
Console.WriteLine(msg.Body.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}



If you run the project, you will see a message-box displaying “Hello, World !”. This message content created by had been sent from MSMQ queue, received by another MSMQ, and processed. In our example both the sending and the receiving queues exist in the same application for the sake of simplicity. In real world applications they reside in very different areas.

This is a very basic introduction to MSMQ and non-transactional queues. In future posts, we will explore more advanced topics in MSMQ.