Microsoft Message Queuing Services (MSMQ) Integration

August 3, 1999

Summary: The purpose of this paper is to describe various ways in which Microsoft® Message Queuing Services (MSMQ) can be used with other technologies to produce a complete enterprise solution. (11 printed pages)

Using MSMQ from within Active Server Pages

Active Server Pages (ASP) makes building server-side processing into your Web applications a straightforward process. Since MSMQ objects are available from within ASP, you can easily take advantage of MSMQ functionality from your Web applications.

The following code shows an example of using MSMQ objects with ASP. This is a subroutine that can be included and called from code in an ASP page. This code creates an instance of the MSMQQueueInfo object. It has properties to hold information about a queue (such as its path name) and a method used to open a queue for sending or retrieving messages.

This code also creates an instance of the MSMQMessage object. This object represents an instance of a message that can be sent or retrieved from a queue. In this case, the queue is opened for “send” access, as opposed to “retrieve” access. What is more, the queue is opened to “deny none”. This means that other clients will also have access to this queue. The ServerVariables property of the Request object can retrieve many different pieces of information. The code below uses it to get the name of the IIS Web Server on which this code is running. We assume that the MSMQ server is the same server and use the name of the Web server as the name of the MSMQ server in the MSMQQueueInfo.PathName property.

The MSMQQueueInfo.Open method returns a reference to the newly opened queue. This reference is used to manipulate the queue. After the queue has been opened, a message object is created. In this case, the label and body properties of the message object are set to identify the message and set the text that is to be sent. Finally, the MSMQMessage.Send method is called to actually send the message to indicated queue that was previously opened.

<%
Private Sub SendMsg()
   'Invoke the Open method of the MSMQQueueInfo object
   Dim Qinfo 
   Dim Q 

   Set Qinfo=CreateObject ( "MSMQ.MSMQQueueInfo" )

   machinename=Request.ServerVariables("SERVER_NAME")
   queuename="queuename"

   Qinfo.PathName = "\\" & machinename & "\" & queuename

   Const MQ_SEND_ACCESS = 2
   Const MQ_DENY_NONE = 0

   Set Q = Qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
  
   'Create the message
   Dim Qmsg 
   Set Qmsg=CreateObject ( "MSMQ.MSMQMessage" )

   Qmsg.Label = "Message Label"
   Qmsg.Body = "Message Body"
  
   'Invoke the Send method of the MSMQMessage object
   Qmsg.Send Q
  
   'Invoke the Close method
   Q.Close

End Sub

%>

The following procedure shows a subroutine that can retrieve a message from a queue from within an ASP page. The code that retrieves the message below is similar to the send message code above. We, again, assume that the IIS server and the MSMQ server are the same. In this case, of course, the queue is opened for receive access.

As above example, the MSMQQueueInfo.Open method returns a reference to the newly opened queue. This reference is used to manipulate that queue. Next, an instance of the MSMQMessage object is created. The MSMQQueue.Receive method is called next to retrieve messages from the opened queue. Finally, the MSMQQueue.Close method is called to close the queue.

<%

Private Sub ReceiveMsg()
  
   'Invoke the Open method of the MSMQQueueInfo object
   Dim Qinfo 
   Dim Q 

   Set Qinfo=CreateObject ( "MSMQ.MSMQQueueInfo" )

   Dim machinename
   Dim queuename
   
   machinename=Request.ServerVariables("SERVER_NAME")
   queuename="queuename"

   Qinfo.PathName = "\\" & machinename & "\" & queuename

   Const MQ_RECEIVE_ACCESS = 1
   Const MQ_DENY_NONE = 0

   Set Q = Qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
  
   'Invoke the Receive method on the MSMQQueue object
   Dim Qmsg
   Set Qmsg=CreateObject ( "MSMQ.MSMQMessage" )
   ' 0=no transaction, true=WantDestinationQueue, true=WantBody, 100=ReceiveTimeout (millisecs)
   Set Qmsg = Q.Receive(0, true, true, 100)
  
   'Invoke the Close method
   Q.Close
  
End Sub

%>

One of the benefits of using MSMQ in your Web applications is that your site can have a higher degree of reliability than it might otherwise have. Users will have a greater degree of confidence in your site if they are able to dependably accomplish tasks on your site. If you have ever attempted to browse to a valid Web site URL only to find that it is down, you know how frustrating it is when you cannot do what you want to do. Customers do not care that you are in the process of installing the latest service pack or that you are re-booting your database server. Customers only care that they were unable to do what they wanted to do at your site.

MSMQ can help. In a typical scenario, users might enter and submit the information. That information is usually sent to the server for processing. Without MSMQ, every piece of the system that is involved in that processing must be up and running to properly deal with the information. If any piece of the system is down or not working properly, the information may not be processed properly, and as a result, you may also have unhappy customers. If the system uses MSMQ, however, that information can be temporarily stored in an MSMQ queue. By storing information sent from users in MSMQ messages that are in MSMQ queues, users of your Web site can enter information and continue to use your Web application even if your database server, or other essential component, is down. Therefore, information can be temporarily held in an MSMQ queue and then later retrieved and processed when the database server (or other system component) comes back on-line.

MSMQ Integration with Microsoft Transaction Server

One of the benefits provided by Microsoft Transaction Server (MTS) is that it is used to help enterprise applications run economically. Using MTS, COM DLLs can easily share system resources and, therefore, increase the probability that resources will be available when they are needed. These resources can be available to all components in all instances of multi-user applications. In addition, MSMQ message operations can easily participate in an MTS transaction. We will discuss this below.

COM, DCOM, and COM+ enable different software components to communicate with one another. MTS ensures that resources are available to support that communication between the components. However, the assumption is that when software component 1 attempts to communicate with software component 2, both components are running and that the necessary communications infrastructure is available. It is possible, and even likely, that at some point in time, both components will not be running when one attempts to communicate with the other. This is especially true if one organization controls one side of the application, and another organization controls the other side. MSMQ enables the application to continue running in this situation.

There are a number of items to be aware of when building COM DLLs that will be installed into MTS and will interact with MSMQ. These items are not difficult to understand, but they are essential in order to build an efficient and effective enterprise application. The following section discusses some of these items.

Transactional Message Queues

MSMQ and MTS are highly complementary technologies. MTS offers all-or-nothing (atomic) processing and MSMQ offers guaranteed message delivery. Thus, you can build an enterprise application that ensures communication between the parts, regardless of the state of the network, and ensures database integrity, regardless of processing outcome.

As an example of why this feature is important, consider that you can use MSMQ to send a message that will initiate an action that will change data in a database. Also consider that applications will typically send numerous messages to a queue. Suppose message 1 contains information that is to be written to a database table. Suppose message 2 contains an identifier that identifies a record to be deleted from a table. Furthermore, message 3 might contain information that is used to update an existing table row. Suppose the message retrieval process begins, and those database actions also begin to occur. If a network connection is severed before the last message is retrieved and processed, the database could be left in an inconsistent state. In other words, not all messages are retrieved and not all database changes are completed.

This could be bad news if you are not using a transactional queue. You should set up your MSMQ queue as a transactional queue and use it in your application to alleviate problems like this. Transactional queues enable your applications to send messages to, or receive messages from a queue in an all-or-none fashion. Under a transactional message queue, either all of the messages will be retrieved, and optionally processed, or none of them will be retrieved. For instance, if several messages are to be retrieved from a queue in a transaction, but a failure occurs during the transaction, all of the messages that have been retrieved are returned back to the MSMQ queue.

The same goes for sending messages to a queue. If everything goes well, processing continues as normal. However, if any problems arise during the course of the message sending transaction, the transaction can be rolled back and the queue will be returned to the state it was in before the transaction began.

Moreover, if changes were made to your SQL Server database while the messages were sent to or received from the queue, the database can also be returned to its original state. In other words, if your application performs the following operations, the state of both the MSMQ queue and the SQL Server database will be consistent.

To make the state of the MSMQ queue and SQL Server databases consistent

  1. Start MTS transaction.

  2. Retrieve MSMQ message #1.

  3. Update data in SQL Server table.

  4. Retrieve MSMQ message #2.

  5. Update data in SQL Server again.

  6. Rollback MTS transaction.

MSMQ messages and SQL Server data are both returned to their original states if problems occur, thanks to the Microsoft Distributed Transaction Coordinator (MS-DTC). The MS-DTC controls the state of data used by Resource Managers, such as SQL Server and MSMQ. It also decides if a transaction should be committed or rolled back.

The following code shows an example of Visual Basic® code that can be used to send a message to a transactional queue. Remember that only transactional messages can be sent to transactional queues, and transactional queues can only accept transactional messages. This example assumes that we have set a reference to the Microsoft Message Queue Object Library and the Microsoft Transaction Server Type Library from within the Visual Basic environment.

Public Function SendMsg(strSendThis As String) As String

   Dim Qinfo As New MSMQQueueInfo
   Dim Q As MSMQQueue
   Dim Qmsg As New MSMQMessage

    ' IF ANY PROBLEMS OCCUR, ROLLBACK THE TRANSACTION FROM WITHIN THE ERROR HANDLER
   On Error GoTo SendMsgErrorHandler

   Dim ctxObjectContext As ObjectContext
   Set ctxObjectContext = GetObjectContext

   Qinfo.PathName = "machinename\queuename"
   Set Q = Qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

   Qmsg.Body = strSendThis
   Qmsg.Label = "Message Label"

   ' ENSURE THAT THIS CODE IS RUNNING WITHIN AN MTS TRANSACTION. IF IT IS,
   ' SEND MESSAGE AS TRANSACTIONAL. OTHERWISE, SEND IN AN INTERNAL MSMQ TRANSACTION   
   If ctxObjectContext.IsInTransaction Then
     Qmsg.Send Q, MQ_MTS_TRANSACTION
   Else
     Qmsg.Send Q, MQ_SINGLE_MESSAGE
   End If
   Q.Close

    ' CAST OUR VOTE TO COMMIT THE TRANSACTION.
   ctxObjectContext.SetComplete
   Set ctxObjectContext = Nothing
   
   SendMsg = "Send Operation Successful"
   
   Exit Function

SendMsgErrorHandler:
   
   SendMsg = "Send Operation Aborted"
    
    ' ROLLBACK THE MESSAGING OPERATION AND ANY DATABASE CHANGES THAT
    ' HAVE BEEN MADE WITHIN THIS TRANSACTION.
   ctxObjectContext.SetAbort
   Set ctxObjectContext = Nothing

   
End Function

Your messages will need to be retrieved from their queues. The following code shows an example of Visual Basic code that can be used to retrieve a message from a transactional queue.

Public Function ReceiveMsg(strReceivedThis As String) As String

   Dim Qinfo As New MSMQQueueInfo
   Dim Q As MSMQQueue
   Dim Qmsg As MSMQMessage

    ' IF ANY PROBLEMS OCCUR, ROLLBACK THE TRANSACTION FROM WITHIN THE ERROR HANDLER
   On Error GoTo RecvMsgErrorHandler

   Dim ctxObjectContext As ObjectContext
   Set ctxObjectContext = GetObjectContext

   Qinfo.PathName = "machinename\queuename"
   Set Q = Qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)

    ' SET ReceiveTimeout TO ZERO IF YOU WANT CONTROL TO INSTANTLY
    ' RETURN TO YOUR APPLICATION AFTER CHECKING FOR MESSAGES
    ' ON THE QUEUE.
    ' Note: no need to explicitly set the transaction parameter
    '  since the default is to use the current MTS transaction.
    '
   Set Qmsg = Q.Receive(ReceiveTimeout:=0)

   If Qmsg Is Nothing Then
     strReceivedThis = ""
     ReceiveMsg = "No Message on Queue to Receive."
    Else
     strReceivedThis = Qmsg.Body
     ReceiveMsg = "A Message Was Received."
   End If
   
   Q.Close

    ' CAST OUR VOTE TO COMMIT THE TRANSACTION
   ctxObjectContext.SetComplete
   Set ctxObjectContext = Nothing
   
   Exit Function
RecvMsgErrorHandler:

    ' ROLLBACK THE MESSAGING OPERATION AND ANY DATABASE CHANGES THAT
    ' HAVE BEEN MADE WITHIN THIS TRANSACTION.
   ctxObjectContext.SetAbort
   Set ctxObjectContext = Nothing
   ReceiveMsg = "A Problem Occurred While Attempting to Receive Message."
End Function

Although messages can be sent across networks, MSMQ transaction boundaries do not cross those networks. In a possibly disconnected network environment, it isn’t feasible to support distributed transactions for the simple reason that network unavailability between two participating nodes can cause unacceptably long resource locks.  In Figure 1, you can see that the process of sending a message can be rolled back until that message is passed from the sending queue in network 1 to the receiving queue in network 2. On the receiving queue, the process of retrieving a message can be rolled back. Unless specified otherwise, messages are automatically removed from the queue when they are retrieved. If a transaction is rolled back while retrieving messages, those messages that have been retrieved will be returned back to the queue from which they were retrieved.

Figure 1. Messages can be rolled back until passed between queues.

Role-Based Security

MTS security is based on the idea of Roles. Roles are categories of users that have been defined for the application for the purpose of determining access permissions to the application's resources. The developer assigns the roles as symbolic user categories to the application and potentially to finer structures within it—including components, interfaces, methods, or private application resources. These role assignments are then used to determine which user categories have permission to access which elements within the application. When an application uses role-based security, a caller's role membership is checked on every call into the application. If a caller does not belong to a role having permission to access the item being called, the call will fail. Callers are granted access to the application or its resources strictly according to the constraints defined within the roles to which they belong.  The system administrator's job is to populate the roles defined for the application with Windows NT® user accounts and groups. This is a crucial stage in carrying out the application's security policy. Users must be assigned to the roles that correctly represent their relationship to the data and resources they might access through the application.

Assigning groups of users

The preferred way to populate roles with users is to use Windows NT groups. First, you assign a user account to the appropriate groups, and then ensure that the groups are assigned to the appropriate roles. Using Windows NT groups to populate roles makes it easier for you to manage large numbers of users. In enterprise computing environments, it is often difficult to effectively track each user's place within the organization and determine how that maps into the role-based security policy particular to each application. As the number of users, administrators, and applications rises this task becomes increasingly complicated. The most scalable solution is to assign user groups to MTS application roles.

Before you assign any groups to roles, you need to be sure that you understand the application's security policy. Ideally, roles should carry names that suggest who should belong to them, such as "Managers" and "Tellers." In addition, there are descriptions for each role that you can access using the administrative tool that may describe what kinds of users should belong to the role. However, if you are not sure which user groups belong in which roles, consult the documentation that accompanies the application or ask the developer for clarification.

 Figure 2. Similarities between Windows NT Groups and MTS Roles

MSMQ Integration with Exchange

If Microsoft Exchange is a product facilitating the transport of e-mail messages between users, then MSMQ is a product that facilitates the transport of messages between software applications. In the same way that Exchange can be used to send messages of various formats (text-only, Excel Spreadsheets, etc.) to users, MSMQ can be used to send messages of various formats to computer software programs.

Although similar in function, MSMQ and Exchange are complementary technologies and do not compete with each other. What is more, there are some distinct differences between MSMQ messages and e-mail messages, such as guaranteed delivery and more delivery options provided by MSMQ.

The MSMQ Exchange Connector

If MSMQ is for sending messages between software, and Exchange is for sending messages between people, then the MSMQ Exchange Connector (MSMQEC) is the hybrid functionality between the two. The MSMQ Exchange Connector enables you to send messages from an Exchange Server system to an application running in an MSMQ Enterprise. This connection facilitates passing messages between an Exchange mailbox to an MSMQ queue.

MSMQ MAPI Transport

The MSMQ MAPI Transport provides functionality similar to that provided by the MSMQ Exchange connector except that the MAPI transport provides it to MAPI mail clients. This will let you send an e-mail message from your desktop e-mail client to software applications for processing. What’s more, the same software applications can send messages to you. Those messages can be retrieved via your e-mail client.

MSMQ Mail SDK

The MSMQ Mail SDK provides coding interfaces that enable your applications to work with messages that are in MIME (similar to text) format.

Effects on Exchange when Uninstalling MSMQ

Uninstalling MSMQ can have adverse effects on Microsoft Exchange Server unless executed properly. If you uninstall MSMQ, it is important to be sure that the following keys are removed from the Windows® registry. If these keys are not removed, non-fatal error messages may appear from Exchange. The keys are

Server:

\\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Rpc\ServerProtocols\ncadg_mq

 

Client:

\\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Rpc\ClientProtocols\ncadg_mq

MSMQ Integration with MSMQ-MQSeries Bridge

It is a reality that organizations use heterogeneous network types to accomplish the overall organizational goal. To that end, it would be advantageous if MSMQ messages could be passed across network types. Using the MSMQ-MQSeries Bridge (included in SNA Server 4.0 SP 2), MSMQ can send messages to and from IBM’s MQSeries software. MQSeries is message queuing software that performs functions similar to those performed by MSMQ.

IBM has developed versions of MQSeries that run on non-Windows platforms. This means that the combination of the three products; MSMQ, IBM MQSeries and the MSMQ-MQSeries Bridge, can enable your enterprise applications to effectively send messages between Windows NT and other platforms, such as mainframes.

To help ensure successful MSMQ/MQSeries communication, your Windows NT installation should be Windows NT Server Enterprise Edition. After you have established a network link between your Windows NT Enterprise Server-based computer and your MVS mainframe computer, you can begin to set up the message queue communication between MSMQ and MQSeries.

Required software on the Windows NT Enterprise Server-based computer:

After installing all of the required software on the Windows NT Enterprise-based computer, there are some configurations that must be set. These configurations will allow your Windows NT MSMQ computer to send messages to the non-Windows NT-based computer.

These settings are:

Note   Windows NT 4.0 Enterprise Edition must be used on the computer where the MSMQ-MQSeries Bridge is running. This restriction will be lifted in the Windows 2000 operating system; any Windows 2000 Server software will be able of running the Bridge.

Additional Resources

Microsoft Corporation MSMQ Website
www.microsoft.com/ntserver/appservice/exec/overview/MSMQ_Overview.asp

Homer, Alex and David Sussman. Professional MTS & MSMQ Programming with VB and ASP. Wrox, 1998.  ISBN: 1861001460

Alan Dickman. Designing Applications With MSMQ: Message Queuing for Developers. Addison-Wesley, 1998. ISBN: 0201325810

--------------------------------------------

The information contained in this document represents the current view of Microsoft Corporation on the issues discussed as of the date of publication. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication.

This document is for informational purposes only. Microsoft makes no warranties, express or implied, in this document.

©1999 Microsoft Corporation. All rights reserved.

Microsoft, Visual Basic, Windows, and Windows NT are either registered trademarks or trademarks of Microsoft Corporation in the U.S. and/or other countries.  Other products and company names mentioned herein may be trademarks of their respective owners.