Creating a Simple RecorderPlayer

team lib

Creating a Simple Recorder/Player

The first task that any application using MSMQ must perform is creating a message. Earlier in the chapter, you learned about the message flow of an MSMQ application and the construction of a message. Once the queue has a message in it, another application normally retrieves the message and does something with the content.

This section of the chapter shows you the techniques for creating a message recorder and a message player. The message recorder will place a message in the message queue. The message player will retrieve the message and display it on screen. The message will contain a heading, body, and priority level. You can perform a number of other tasks with messages, but this is plenty to start with.

Defining the Message Queue

Before you can send messages to a queue, you have to create the queue. MSMQ allows several methods of creating a message queue. The three most common techniques are

  • Define the queue dynamically by using code.

  • Let COM+ automatically create the queue for you.

  • Create the queue manually by using the Message Queuing snap-in.

We'll take a look at how to perform the third technique, manually creating the message queue by using the Message Queuing snap-in. You'll find this snap-in in the Computer Management console as part of the Services And Applications folder. Within this snap-in, you'll see four folders: Outgoing Queues, Public Queues, Private Queues, and System Queues.

To create the queue for this example, right-click the Public Queues folder and choose New and then Public Queue from the context menu. You'll see a New Object - Public Queue dialog box similar to the one shown in Figure 9-2.

click to expand
Figure 9-2: Create a queue using the New Object-Public Queue dialog box.

Type the name of the queue, Temp , in the Queue Name field. You could also make the queue transactional, but we don't need that feature for this example. Click OK, and the new queue will appear, as shown in Figure 9-3.

click to expand
Figure 9-3: The new queue will appear as part of the Public Queues folder.

Notice the organization of the queue. The Queue Messages folder, which contains messages the queue has received, and the Journal Messages folder, which contains messages that indicate events such as delivery failures, are default entries.

The Triggers folder contains a list of applications that react to the messages in the queue. A trigger application can be as simple as a standard Windows application assigned to work with the queue or a COM+ application designed to act as a listener. MSMQ provides several levels of application support. For example, an application can react to the messages in a serialized manner, which means it tests all rules against the message before it moves on to the next message in the queue. You can also choose the level of message retrieval. Some applications might require only the Peeking level of support, while others might require the Retrieval or Transactional Retrieval level.

Accessing the Message Queue

Visual Studio .NET makes it easy to access the queues on any system for which you have access. Simply open a connection to the server in Server Explorer and select the queue you want to use. Figure 9-4 shows a typical example.


Figure 9-4: Creating a queue connection in Visual Studio .NET is as easy as finding it in Server Explorer.

To use the queue, drag it from Server Explorer and drop it into your application. This action creates a System.Messaging.MessageQueue object that will appear in the area below the dialog box in the Designer window. The sample application adds two text boxes, a combo box, and some push buttons to send the message. Figure 9-5 shows the test application layout.

click to expand
Figure 9-5: The layout of the sample recorder application

Creating the Recorder

Writing the source code for this example is relatively simple because the integrated development environment (IDE) does most of the work for you. Listing 9-1 shows the code you'll need for this example. You'll find the source code in the Chapter 09\Recorder folder of the book's companion content. You can download this content from the book's Web site at http://www.microsoft.com/ mspress/books/6426.asp .

Note 

When you add a queue to a project using Server Explorer, the resulting MessageQueue object will have a Path property value that includes both the machine name and the location of the queue. For example, the source code for this example will include a Path property value of main\Temp . You must modify the machine name, main , to match the name of your server. Otherwise, the path won't point to the proper location on your system. If you are using a two-machine setup, which is the recommended configuration for the examples in this chapter, don't use the generic '.' operator. Using the '.' operator in the form .\Temp will point the queue to the local machine, which won't test the connection between the two machines.

Listing 9-1: Creating a message
start example
 privatevoidbtnSend_Click(objectsender,System.EventArgse) { System.Messaging.MessageMsg;//Messagetosend. //Createthemessagecontent. Msg=newSystem.Messaging.Message(); Msg.Label=txtMessageHeader.Text; Msg.Body=txtMessage.Text; Msg.Priority=(MessagePriority)cbPriority.SelectedIndex; //Sendthemessage. TempMQ.Send(Msg); } 
end example
 

As you can see from the sample code, sending a message to a message queue isn't hard, especially when compared to the requirements of older versions of Microsoft Visual Studio. All you need to do is create the Message object, fill it with data, and then use the Send() method of the message queue object to send it to the message queue.

Testing the Recorder

Run the application, change any of the entries that you want, and then click Send. After a second or two, you'll see the message appear in the Public Queues folder. You might have to use the Refresh command to force the message to appear. Once the test message does appear, it will contain the heading in the Label column, the priority in the Priority column, and other information such as a message ID. Figure 9-6 shows a typical entry.

click to expand
Figure 9-6: After the application sends the message, you'll see it appear in the message queue.

When you double-click the message, a Properties dialog box appears that allows you to see the various message elements. For example, the User tab contains the sending user 's name and Security Identifier (SID). You can also learn whether Windows authenticated the message and determine whether the sender encrypted the message. We didn't perform either of these tasks for the example.

The most interesting part of the message is the Body tab. Older versions of MSMQ relied on a custom format to store the message content. You might be surprised to learn that the newest version stores messages in XML format, as shown in Figure 9-7. Using an XML format makes it easier to use MSMQ in a distributed application environment that relies on the Internet for connectivity.

click to expand
Figure 9-7: The body of the message will appear in XML format rather than the custom format used by older versions of MSMQ.

Creating the Player

At some point, you'll want to retrieve the messages in the queue. You can perform this task by using a number of techniques. The simplest technique is to write an application that looks for the queue, determines whether the queue contains a message, and then displays the content of the message if one exists. That's precisely what the example in Listing 9-2 does.

Listing 9-2: Retrieving a message
start example
 privatevoidbtnReceive_Click(objectsender,System.EventArgse) { System.Messaging.MessageMsg;//Messagetoreceive. //Setthequeueformatter. TempMQ.Formatter=newXmlMessageFormatter(newType[]{typeof(String)}); //Setthequeuepriorityfilter. TempMQ.MessageReadPropertyFilter.Priority=true; //Getthemessage. try { Msg=TempMQ.Receive(newTimeSpan(5)); } //Ifthetimespanelapsesbeforethemessagearrives, //MSMQwillthrowanexception. catch(MessageQueueExceptionMQE) { MessageBox.Show("NoMessagestoRetrieve\r\n" + MQE.Message,  "MessageError", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } //Displaythemessage. MessageBox.Show("Label: " +Msg.Label+  "\r\nBody: " +Msg.Body+  "\r\nPriority: " +Msg.Priority.ToString(),  "MessageContents", MessageBoxButtons.OK, MessageBoxIcon.Information); } 
end example
 

The code for retrieving a message is slightly more complicated than the code used to create it. The code begins by creating an XmlMessageFormatter object. Remember that MSMQ stores the message in XML format, so you need some way to retrieve the information. As part of defining the XmlMessageFormatter object, you must decide which data formats to retrieve. In this case, because the only content the message contains is a string, we need to provide only the String type.

To keep the amount of information overload an application has to handle to a minimum, the System.Messaging.MessageQueue object automatically filters the content. In some cases, it filters too much content and you need to request that the object send it as part of the message. That's what the TempMQ.MessageReadPropertyFilter.Priority property does in this case-setting it to true means that the message will contain priority information. (It normally doesn't.)

The Receive() method obtains a message from the queue. If you don't specify a TimeSpan for the call to wait, it will continue waiting until the queue has a message. Consequently, the call includes this information in the example. If the call returns before the queue contains a message, it will throw a MessageQueueException exception. That's why the call appears within a trycatch block.

As you can see, the code for displaying the information isn't complex. The Label and Body properties appear as strings. The Body property is a string only because the XmlMessageFormatter object converts it for you. The property is actually listed as an object, and you shouldn't assume the message always contains a string (although it does contain one in this case). The code will always need to convert the Priority property to a string equivalent. Now that you know how the player works, you can test it. Figure 9-8 shows the output of this example using the default message inputs. Notice that the priority is listed as text, rather than as a number, because the original value is an enumeration.


Figure 9-8: Retrieving the content of a message queue requires a little formatting.
 
team lib


COM Programming with Microsoft .NET
COM Programming with Microsoft .NET
ISBN: 0735618755
EAN: 2147483647
Year: 2006
Pages: 140

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net