Revisiting Microsoft Message Queuing (MSMQ)


The MSMQ product is Microsoft's Windows platform solution to compete against IBM's MQSeries product and similar products. Any exposure that you have had to the MQSeries product will act as transferable knowledge now for this chapter's MSMQ discussion.

Note  

IBM has recently announced that they are renaming and rebranding the MQSeries product. They have merged the MQSeries product with the WebSphere product family to become WebSphere MQ ( http://www-3.ibm.com/software/ts/mqseries/mq_renaming.html ).

Given that, I won't spend time reminding you that these "messaging" types of products have more to do with the storage of data into queues than they do with the storage of messages . [5] I can only hope that you'll forgive me for not mentioning how a messaging product such as MSMQ helps to provide a connectionless type of guaranteed delivery between disparate systems and components . Instead, I'll spend time exploring ways that a .NET application can use MSMQ and demon strating how MSMQ can be used as part of a distributed processing model.

In this section, you'll learn that you can easily access the MSMQ product from within VS .NET using the Server Explorer window feature. Therefore, as long as you have VS .NET open , you don't necessarily need to be reminded that you can also access MSMQ via the snap-in in the Computer Management console (click the Start button and select Programs Administrative Tools Computer Man agement or simply right-click your My Computer icon and choose Manage).

Note  

As you recall, Chapter 19 explored the topic of MSMQ as part of the introduction to the Queued Components COM+ feature. At that time, I mentioned the requirement of having MSMQ installed. [6] Additionally, there is the requirement that the Message Queuing service be started. These requirements are equally applicable for this chapter's discussion.

Now, let's look at some code.

Setting Up for the Sample Applications

To begin, you will create two sample applications: MyMSMQExampleCOBOL and MyMSMQExampleVB (COBOL .NET and VB .NET, respectively). Both samples use the Windows Application project template. The SQL Server “ and ADO.NET- related code used in each sample project was "borrowed" from Chapter 18's demon stration applications (the applications named MyEnhancedInformativeWinFormCobol and MyEnhancedInformativeWinFormVB).

To keep things interesting, I have created an "interoperability" opportunity. You will use the COBOL .NET sample application to implement logic that will load the MSMQ queue. Then, the VB .NET sample application will access the same MSMQ queue to retrieve the loaded message. This architecture will show that an MSMQ queue can be shared between different applications ”even applications written in different languages. Having multiple applications interact in this fashion is one way to achieve interoperability.

Specifically, the sample applications will be designed to accomplish the following:

  • The MyMSMQExampleCOBOL sample application will expose functionality to connect to the Northwind SQL Server sample database.

  • The MyMSMQExampleCOBOL sample application will create and load an ADO.NET Dataset.

  • The MyMSMQExampleCOBOL sample application will load the ADO.NET Dataset into an MSMQ private queue named "myMSMQexample".

  • The MyMSMQExampleVB sample application will retrieve the ADO.NET Dataset from MSMQ.

  • The MyMSMQExampleVB sample application will display the retrieved ADO.NET Dataset using a DataGrid control.

MSMQ is a tool that you can use to easily enable your applications to interact. The application process model demonstrated in this section is best described as being both distributed and interoperative (see Figure 20-1).

click to expand
Figure 20-1: Application flow for the MyMSMQExampleCOBOL and MyMSMQExampleVB sample applications

To get things set up for the demonstration, I need to actually create an MSMQ queue. As previously mentioned, on this occasion I will demonstrate the approach of accessing MSMQ from within the VS .NET IDE. Keep in mind that you always have the choice to access MSMQ from the Computer Management console . Now you'll quickly walk through the steps of accessing MSMQ from within the VS .NET IDE:

  1. Open the VS .NET IDE Server Explorer window. From your VS .NET IDE Standard toolbar, select View Server Explorer. Optionally, press Ctrl-Alt-S (see Figure 20-2).


    Figure 20-2: Accessing the VS .NET IDE Server Explorer window

  2. Expand the Message Queues node. Observe the existence of the Private Queues, Public Queues, and System Queues nodes (see Figure 20-3). Also, notice that you can access other "server"-type products from the Server Explorer window (i.e., SQL Server, Event Logs, and so forth).


    Figure 20-3: The VS .NET IDE Server Explorer window showing the Message Queues node and nodes for several other server products

  3. Create a new MSMQ private queue by right-clicking the Private Queues node and selecting Create Queue (see Figure 20-4). If your computer is connected to a local area network (LAN), you might explore the use of the Public Queues node. The System Queues node is used by the system.


    Figure 20-4: Preparing to create a new MSMQ private queue

  4. Name the private queue. For this demonstration, I chose the name "myMSMQexample". Notice the "Make queue transactional" check box. Leave this box unchecked. You can experiment with this option later when you extend the sample applications. Click OK after you have entered the name (see Figure 20-5).

    click to expand
    Figure 20-5: Entering the name for the new private queue

That's it! As shown in Figure 20-6, the newly created MSMQ private queue is ready for use.


Figure 20-6: The new myMSMQexample private queue is ready for use.

Completing the Sample Applications

Now that you've created your new MSMQ queue, it's time to complete the sample applications. First, you'll add a few basic controls to the Windows Form of both MyMSMQExampleCOBOL and MyMSMQExampleVB. Next , you'll add your own myMSMQexample MSMQ private queue to each project.

To do this, first prepare your VS .NET windows such that you have both the Server Explorer window and the sample application MyMSMQExampleVB open. Then, while you are viewing the Form1.vb Windows Form in Design view, drag and drop the myMSMQexample MSMQ queue from the Server Explorer window to the Design view of the Form1.vb Windows Form (see Figure 20-7).

click to expand
Figure 20-7: The MyMSMQExampleVB project showing the myMSMQexample MSMQ private queue in the VS .NET components tray with the default name of MessageQueue1
Tip  

Dragging and dropping the MSMQ queue onto your design surface will look and feel like the familiar task of dragging and dropping controls from the VS .NET Toolbox. Other server-type products shown in the Server Explorer window also support the drag-and-drop approach.

Repeat this dragging and dropping procedure for the MyMSMQExampleCOBOL project (see Figure 20-8).

click to expand
Figure 20-8: The MyMSMQExampleCOBOL project showing the myMSMQexample MSMQ queue in the VS .NET components tray with the default name of MessageQueue1
start sidebar
Changing the Path Value

Viewing your open project in the VS .NET IDE (Design view), take a moment to view the property pages (right-click the MessageQueue1 icon located in the component tray and select Properties or select the MessageQueue1 icon and press F4) for MessageQueue1, which sits in the component tray. Among the properties exposed, you will notice a Path property. Basically, this associates this instance of the System.Messaging.MessageQueue class to your private queue myMSMQexample.

When you use the Server Explorer MSMQ drag-and-drop feature, you will want to be aware that leaving the Path value at its default setting will limit your message queues to only being functional on the original computer used during initial development. Why? Notice that the default Path value appends the name of your development machine to the remaining portion of the Path. In most real- life development scenarios, you will want to change the Path value to be more generic . That is, if you plan to deploy your application to other machines, you will want the Path value to be more generic. You accomplish this by editing the Path value machineName /Private$/QueueName by replacing machineName with a period (.). The end result is ./Private$/QueueName. Optionally, consider creating your MSMQ queues dynamically in code during runtime (i.e., Dim MessageQueue1 As New System.Messaging.MessageQueue(".\Private$\MyMSMQExample" ).

You will come across application design considerations where the dynamic approach may be more appropriate (sometimes it is more efficient). In other cases, you may find that the Server Explorer drag-and-drop feature (a RAD feature) will meet your needs. Be aware of your choices and choose wisely. (The sample applications use this generic path approach to enable proper MSMQ functionality on multiple machines.)

end sidebar
 

All that is left now is to add a few lines of code. The code snippet in Listing 20-1 shows the pertinent portions of code that were added to the MyMSMQExampleCOBOL sample application.

Listing 20-1: Code Snippets from the MyMSMQExampleCOBOL Sample Application
start example
 000010 IDENTIFICATION DIVISION. 000020 CLASS-ID. Form1 AS "MyMSMQExampleCOBOL.Form1" 000030    INHERITS CLASS-FORM. 000040 ENVIRONMENT DIVISION. 000050 CONFIGURATION SECTION. 000060 SPECIAL-NAMES. 000070    CUSTOM-ATTRIBUTE STA-THREAD CLASS CLASS-STA-THREAD 000080 . 000090 REPOSITORY. . . . 000300    CLASS CLASS-GUID AS "System.Guid" 000310    CLASS CLASS-MESSAGEQUEUE AS "System.Messaging.MessageQueue" . . . 000920 STATIC. 000930 DATA DIVISION. 000940 WORKING-STORAGE SECTION. 000950 PROCEDURE DIVISION. 000960 000970 METHOD-ID. MAIN AS "Main" CUSTOM-ATTRIBUTE IS STA-THREAD. 000980 DATA DIVISION. 000990 WORKING-STORAGE SECTION. 001000 01 TEMP-1 OBJECT REFERENCE Form1. 001010 PROCEDURE DIVISION. 001020    INVOKE Form1 "NEW" RETURNING TEMP-1. 001030    INVOKE CLASS-APPLICATION "Run" USING BY VALUE TEMP-1. 001040 END METHOD MAIN. 001050 001060 END STATIC. 001070 001080 OBJECT 001090 . 001100 DATA DIVISION. 001110 WORKING-STORAGE SECTION. 001120 01 myGUID OBJECT REFERENCE CLASS-GUID. . . . 001370 PROCEDURE DIVISION. 001380 001390 METHOD-ID. NEW. 001400 PROCEDURE DIVISION. 001410    INVOKE SELF "InitializeComponent". 001420 END METHOD NEW. . . . 025940 METHOD-ID. button1_Click PRIVATE. 025950 DATA DIVISION. 025960 WORKING-STORAGE SECTION. 025970 01 MyNewConnectionString PIC X(100). 025980 01 MyNewAppSettings OBJECT REFERENCE CLASS-NAMEVALUECOLLECTION. 025990 01 MyGUIDString PIC X(50). 026000 026010 LINKAGE SECTION. 026020 01 sender OBJECT REFERENCE CLASS-OBJECT. 026030 01 e OBJECT REFERENCE CLASS-EVENTARGS. 026040 PROCEDURE DIVISION USING BY VALUE sender e. . . . 026980    INVOKE mySqlDataAdapter "Fill"  026990      USING BY VALUE myDataSet, "myCategories" 027000  . . . 027100  027110    SET mySqlConnection TO NULL. 027120    SET mySqlDataAdapter TO NULL. 027130    SET mySqlCommand TO NULL. 027140    SET myDataTable TO NULL. 027150  . . . 027210    SET myGUID TO CLASS-GUID::"NewGuid"() 027220    SET MyGUIDString TO myGUID::"ToString"() 027230    INVOKE messageQueue1 "Send"  027240    USING BY VALUE myDataSet, MyGUIDString 027250    SET PROP-TEXT OF label1 TO "MSMQ Message has been Sent!" 027251    SET PROP-TEXT OF label2 TO MyGUIDString 027260  027270 END METHOD button1_Click. 027280 027290 END OBJECT. 027300 END CLASS Form1. 
end example
 

Please take a moment to read through the code in Listing 20-1. To save space, I left out the portions of the application (the ADO.NET-related code) that you've seen before. You'll notice that the bulk of your concerns are between lines 027210 and 027251 of the code. Lines 000300 and 000310 are rather important as well. I'm sure you get the point.

Listing 20-1 shows that the System.Messaging.MessageQueue class is refer enced to expose the private queue that you dragged and dropped onto the form from the Server Explorer window. Then, on line 027230, the Send method is invoked to "send" a message to your MSMQ private queue, myMSMQexample.

You may have noticed the addition of the GUID class in the sample code (in line 027210). I included this mainly for fun. No, actually, this is my way of pro viding a rock-solid and proven demonstration showing that the same MSMQ message that you "send" to the myMSMQexample queue is exactly the same message that you later "receive" from the same myMSMQexample queue. [7] After all, a globally unique identifier (GUID) is virtually guaranteed to be unique. In real life, you might use a more meaningful ID for the message label.

The only other thing to mention for the MyMSMQExampleCOBOL sample is related to the choice to "send" an ADO.NET Dataset. You might wonder if you can send other things ”other classes, other objects, and so forth. There are basically two restrictions:

  • The "message" item is limited to a 4MB size .

  • The "message" item has to be serializable.

That is it. The size has to be reasonable and you need to be able to serialize the object that gets stored as an MSMQ message.

Just in case you were wondering how I knew that the ADO.NET Dataset met the serializable requirement, take a look at Figure 20-9. As you can see from the portion of the VS .NET Help text, the System.Data.Dataset class is decorated with the <serializable> attribute. Additionally, notice that the ISerializable interface is implemented. Keep these points in mind if and when you get around to creating your own custom classes as MSMQ message candidates.

click to expand
Figure 20-9: A portion of the VS .NET Help text for the System.Data.Dataset class. Many other .NET Framework classes are serializable, and you can also create your own serializable classes.
Tip  

The System.Data.DataTable class is also marked as being serializable. From what I have noticed, all of the basic data types are also marked as serializable (System.String, System.Int32, System.Array, and so forth).

The last portion of setup for your sample applications deals with the MyMSMQExampleVB sample application. Recall that you will use the VB .NET project to "receive" the message from your private MSMQ queue. The code snippet in Listing 20-2 shows the relevant code used in the MyMSMQExampleVB sample application. This listing represents the code used in the Button3_Click event/method.

Listing 20-2: Code Snippet Taken from the MyMSMQExampleVB Sample Application
start example
 Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As      System.EventArgs) Handles Button3.Click       Dim myNewDataset As System.Data.DataSet       Dim myMessage As System.Messaging.Message       Try             MessageQueue1.Peek(New TimeSpan(0))                 myMessage = MessageQueue1.Receive             myMessage.Formatter = New _             System.Messaging.XmlMessageFormatter(New Type() {GetType(DataSet)})             myNewDataset = CType(myMessage.Body, DataSet)                 '****************************************************             With DataGrid2                     .Visible = "True"                     .DataSource = myNewDataset                     .DataMember = "myCategories"             End With             Button3.Text = "MSMQ Message removed from Queue"             Label1.Text = myMessage.Label       Catch myexception As System.Messaging.MessageQueueException             If myexception.MessageQueueErrorCode = _                  System.Messaging.MessageQueueErrorCode.IOTimeout Then                  MsgBox("Please Load the MSMQ Message first")             End If       End Try       'Example code to Load MSMQ Private Queue       'Dim myGuid As String = System.Guid.NewGuid.ToString       'MessageQueue1.Send(myDataset, myGuid) End Sub 
end example
 
Note  

Though it's not shown here, the VS .NET Solution Explorer window indicates that a reference has been added to the System.Messaging assembly.

Take a moment to review Listing 20-2. You will see that an object is created for the System.Messaging.Message class to expose properties and methods . Otherwise, observe that the Peek and Receive methods are used on the messageQueue1 object. Many other useful classes are available for use in the System.Messaging namespace. Definitely consider familiarizing yourself with this feature- and class-rich namespace .

To get the whole demonstration up and running, simply run both sample projects (MyMSMQExampleVB and MyMSMQExampleCOBOL). If you want, you can start with the COBOL .NET-versioned project to send the MSMQ message. As shown in Figure 20-10, the GUI for MyMSMQExampleCOBOL indicates that an MSMQ message has been sent. Notice the GUID displayed on the form.

click to expand
Figure 20-10: After executing the MyMSMQExampleCOBOL sample application

View the MSMQ private queue in the VS .NET Server Explorer window before executing the MyMSMQExampleVB sample application. As shown in Figure 20-11, the sent message shows in the myMSMQexample private MSMQ queue. Notice that the GUID (as the message label) is displayed alongside the message.

click to expand
Figure 20-11: The myMSMQexample private MSMQ queue with one message

Next, run the MyMSMQExampleVB sample application. If you click the button at the top-right corner of the form, you will receive the one MSMQ message from your myMSMQexample private MSMQ queue (see Figure 20-12). Notice the GUID displayed on the form.

click to expand
Figure 20-12: After executing the MyMSMQExampleVB sample application

Before you send another message with the MyMSMQExampleCOBOL sample application, proceed to click the same button on the MyMSMQExampleVB sample application again. As shown in Figure 20-13, a message box will appear.


Figure 20-13: The message box logic is coded as part of the exception-handling response.

Any previous experience that you have had with the IBM MQSeries product (perhaps on the mainframe) will have acquainted you with the expected behavior of a message being deleted from the queue after it was received. As you know, this is normally a desired feature: guaranteed, one-time delivery. Naturally, you can change your code slightly to implement logic that will receive but not delete an MSMQ message.

You may notice that when you look at the VS .NET Server Explorer window, the MSMQ message still appears even after it has been deleted (or it does not appear after it has been sent). If you refresh the display (as shown in Figure 20-14), the most current content status will correctly display.

click to expand
Figure 20-14: Refreshing the MSMQ Queue display from the VS .NET Server Explorer window

You can extend both sample applications to use other MSMQ features. For example, you can explore the option of making your queue transactional. So far, I have described only a couple of the most basic MSMQ features to give you a general idea and possibly point you in the right direction. In the next section, you will explore the MSMQ tool a bit further.

Note  

The previous examples' approach demonstrated the use of MSMQ in a synchronous processing model. MSMQ supports both the synchronous and asynchronous processing models.

[5] Of course, this would depend on your definition of the word "messages." If you strictly define the word to only apply to e-mail messages, then you might be better served looking into a product like Exchange Server. However, if you loosely define the messages to include any serializable object, then a product like MSMQ just might make a good fit into your architecture.

[6] The MSMQ product is a free bundled feature on the Windows XP and Windows 2000 operating systems.

[7] In other words, this is not a "smoke-and-mirrors" demonstration. The same can be said for each demonstration sample application found throughout this entire book. Unfortunately, the same is not always true with some of the sample applications floating about in the public domain and in some conferences. Programmer, beware!




COBOL and Visual Basic on .NET
COBOL and Visual Basic on .NET: A Guide for the Reformed Mainframe Programmer
ISBN: 1590590481
EAN: 2147483647
Year: 2003
Pages: 204

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