We learn in Chapter 10, "Queued Components," that Queued Components rely on MSMQ for asynchronocity. The queue moniker is used to instantiate queued components and can also be used to set MSMQ-specific properties affecting how messages are delivered to these components. This gives the COM+ client author some additional control over how and where MSMQ ultimately delivers its method calls. For example, consider the following moniker string:
Set b = GetObject("queue:MaxTimeToReachQueue=10/new:Some.Component")
The
MaxTimeToReachQueue
parameter shown here allows you to specify the maximum time a message has to reach its destination queue before an error is triggered. If you are using MSMQ directly, you will find that one of the properties of an MSMQMessage
object is MaxTimeToReachQueue
. Most of the string parameters that queue monikers are designed to understand have direct property equivalents at the MSMQ level.
COM+ exposes only a subset of all the message attributes available directly through MSMQ, because many of these attributes are populated by COM+ itself. (The
Extension
attribute, for example, is populated by COM+ and thus is not exposed as a moniker parameter.)
Some important parameters that can be specified using the queue moniker are given in the following sections. These can be grouped into two sets: one set that affects the queue the message is sent to and another that affects the message itself.
In MSMQ, there are two ways to specify the location of a queue. One way is to use the FormatName
property, which allows you to specify the queue location in a number of different formats. The second way is the PathName
property. I will discuss the former first.
FormatName
can take on the following variations:
FormatName=PUBLIC=QueueGUID
FormatName=PRIVATE=MachineGUID QueueNumber
FormatName=DIRECT=Protocol:MachineAddress QueueName
FormatName=DIRECT=OS:MachineName QueueName
Let's consider each option in turn.
You can only use the PUBLIC
specifier when operating on an Active Directory network. This option requires that you know the GUID of the queue you want to communicate to, as in the following:
Example: FormatName=PUBLIC=984A8A7E-6054-42e3-A4C4-F94F3D2DF55A
If you know the computer name and queue name, this GUID value can be obtained by using the MSMQ API function MQPathNameToFormatName
. This API takes a given PathName
(MachineXQueueY) and provides you with the PUBLIC
GUID of that queue. If you have the path name, however, you can use the PathName
attribute listed in the next section, "
PathName.`" This option is really for the rare cases where you only have the queue GUID.
FormatName=PRIVATE=MachineGUID QueueNumber
Use the PRIVATE
specifier to access private queues on the network. Private queues are not registered in Active Directory and require that you specify the machine GUID and the queue number of the destination queue, as in the following:
Example: FormatName=PRIVATE=AE4D13C4-CE13-4fea-8B8C-0C75FBE47BE8 0000000ff
The machine GUID can be obtained using the MSMQ: MQGetMachineProperties
API.
FormatName=DIRECT=OS:MachineName QueueName
The DIRECT
specifier is useful when working with networks that don't have Active Directory or to access queues outside an Active Directory network. Also note that in a Workgroup setup (a network without Active Directory), the only way to access a remote queue is to use the DIRECT
specifier.
The DIRECT
specifier has two parts: the address specifying the location of the destination machine and the name of the queue on that machine. You can specify one of the supported protocols and address (TCP/SPX) or use the computer's underlying protocol and specify the machine name using the OS specifier. The following are all valid examples:
Examples: FormatName=DIRECT=OS:Sajid SajidsQueue FormatName=DIRECT=TCP:202.10.6.12SajidsQueue FormatName=DIRECT=SPX:00000322:00b3335f1551SajidsQueue
For private queues, note that the queue name is preceded by the Private$
specifier:
FormatName=DIRECT=OS:SajidPrivate$SomePrivateQueue
The PathName
parameter is used very much like the last two variants (of the FormatName
parameter. It allows you to specify the full path name of the destination queue. Use this parameter by specifying both the computer and queue name, as in the following:
PathName=SajidSajidsQueue PathName=SajidPrivate$ SomePrivateQueue
You can also specify that the local machine should be used by using the . specifier, as in the following:
PathName=.SajidsQueue PathName=.Private$SomePrivateQueue
This attribute has a maximum string length of MQ_MAX_Q_NAME_LEN
characters, which at the time of this writing is 124 UNICODE characters.
There are two additional moniker parameters that COM+ allows you to specify to determine the location of the destination queue. Recall that the PathName
parameter consists of two parts: the computername
and the queuename
. COM+ allows you to specify these individually using the appropriately named ComputerName
and QueueName
parameters.
Thus, the following two initialization strings are the same:
Set b = GetObject("queue:PathName=SajidSajidsQueue/new:Some.Component") Set b = GetObject("queue:ComputerName=Sajid,QueueName=SajidsQueue/ new:Some.Component")
COM+ is amalgamating the QueueName
and ComputerName
parameters in the second string, to produce the PathName
in the first string.
If you use the QueueName
parameter by itself, COM+ assumes the ComputerName
to be the local computer. Thus, the following two moniker strings are also the same:
Set b = GetObject("queue:PathName=.SajidsQueue/new:Some.Component") Set b = GetObject("queue:QueueName=SajidsQueue/new:Some.Component")
The only complication that arises is when you use the ComputerName
parameter without using the QueueName
parameter. Consider the following string:
Set b = GetObject("queue:ComputerName=AnotherComputer/new:Some.Component")
In this case, how does COM+ determine what queue it will smessages to on AnotherComputer
? COM+ makes an educated guess based on the local configuration. Remember that the destination queue is determined by the name of the COM+ application in which the component resides. Because no QueueName
has been specified on the remote machine, COM+ uses the local application to determine the queue it should sto. (This is why a queued component must be installed locally, even if it will only be run on remote machines.)
Thus, if the COM+ applications housing the queued component are named differently on the local and remote machines (and hence their respective queues are different), COM+ sends the message to the wrong queue on the remote machine—if it exists in the first place. However, queued components exhibit some interesting behavior if this happens; when a COM+ application receives a message not meant for it, it re-routes the message to the proper COM+ application housing the intended component. In addition, unauthenticated messages get authenticated during the process.
The parameters described in the following sections affect the underlying MSMQ message sent on behalf of the queued component.
AppSpecific
(long) allows you to specify application-specific information to be used by the receiver of the message. This doesn't make sense in the context of Queued Components, because the receiver of the message is most likely the QC.Player, which discards this information anyway. Below is an example of using the AppSpecific
parameter:
Set b = GetObject("queue:AppSpecific=2000/new:Some.Component")
AuthLevel
(long) determines whether MSMQ should authenticate the messages it sends out. The default value for this attribute is derived from the local application housing the component in question. This attribute gives you explicit control over authentication and is useful in situations where the destination queue resides on a remote computer. It can either be turned ON (MQMSG_AUTH_LEVEL_ALWAYS
) or OFF (MQMSG_AUTH_LEVEL_NONE
). The following line of code tells MSMQ to authenticate all the messages it sends out:
Set b = GetObject("queue:AuthLevel=MQMSG_AUTH_LEVEL_ALWAYS/new:Some.Component")
Delivery
(long) determines if the message being sent is written to disk prior to the delivery attempt. You specify that the message should be written to disk by setting this value to MQMSG_DELIVERY_RECOVERABLE
. If speed is of the essence and you are willing to sacrifice the durability this option provides, you can turn it off by setting this value equal to MQMSG_DELIVERY_EXPRESS
. Bear in mind that if the destination queue is transactional, COM+ automatically sets this option to MQMSG_DELIVERY_RECOVERABLE
, such that the message can be sent repeatedly if required. The line of code below tells MSMQ NOT to write messages to disk before it sends them out:
EncryptAlgorithm
(long) allows you to specify the algorithm MSMQ uses to encrypt outgoing messages. The following are two options that are available:
The code below tells MSMQ to encrypt messages using the RC4 encryption scheme:
Set b = GetObject("queue:EncryptAlgorithm=CALG_RC4/new:Some.Component")
Consult the MSDN documentation on the Crypto API for information regarding these encryption techniques. The portions of your message that are encrypted using the specified technique can be specified using the PrivLevel
attribute.
HashAlgorithm
(long) determines the hash algorithm MSMQ will use to authenticate the message. MSMQ uses such algorithms to compute a hash value based on the body of the message being sent. It attaches this value to the message itself. When the recipient receives it, it computes a hash value using the same algorithm and compares it to the attached value. If they match, the message is said to be authentic—that is, the contents of the body haven't changed during transmission of the message.
You can specify any of the following algorithms: CALG_MD2
, CALG_MD4
, CALG_MD5
, CALG_SHA
, CALG_SHA1
, CALG_MAC
, CALG_SSL3_SHAMD5
, CALG_HMAC
, or CALG_TLS1PRF
.
Set b = GetObject("queue:HashAlgorithm=CALG_MD5/new:Some.Component")
Consult the Crypto API documentation for specific information on each.
Journal
(long) determines what happens when a message is retrieved from the queue it has been sent to. Options for this attribute are the following:
MQMSG_JOURNAL_NONE
. Messages are discarded after they are retrieved from the queue.
MQMSG_DEADLETTER
. Messages are moved to the deadletter queue (sometimes referred to as the Dead Message Queue) after they are retrieved.
MQMSG_JOURNAL
. Messages are moved to the journal queue after they are retrieved. This is the default setting.
Label
(string) allows you to specify a string describing the message. If you specify this attribute, all messages that COM+ sends for this queued component will contain the label you specify. Keep in mind that the label
attribute has no effect on the operation of queued components themselves and is really only used for information purposes as shown in Figure E.1.
Set b = GetObject("queue:Label=Your-Label-Here/new:Some.Component")
This attribute has a maximum string length of MQ_MAX_MSG_LABEL_LEN
characters, which at the time of this writing is 250 UNICODE characters.
MaxTimeToReachQueue
(long) determines the maximum amount of time the message has to reach its destination queue, before it is moved to the location specified by the Journal
attribute. This attribute can take on the following values:
Alternatively, you can specify the number of seconds a message will wait in the queue before it is removed to its alternate location. Used in conjunction with the JournalMQMSG_DEADLETTER
setting, this option can be used to trigger an Exception class if the message is not sent within a given amount of time.
MaxTimeToReceive
(long) is similar to the MaxTimeToReachQueue
attribute—the difference being that it specifies the amount of time the message has to be removed from its destination queue, before it is moved to the location specified by the Journal
attribute. Like the MaxTimeToReachQueue
property, this attribute can take on three values: INFITE
, LONG_LIVED
, or an integer equal to the number of seconds to wait.
Priority
(long) determines the priority of the message being sent. MSMQ uses this value to give preference to higher priority messages during the routing process and also to determine where the message is placed in the queue itself. This attribute can take on one of the following values: MQ_MIN_PRIORITY
(0), MQ_MAX_PRIORITY
(7), MQ_DEFAULT_PRIORITY
(3), or a number between 0 and 7.
Set b = GetObject("queue:Priority=MQ_MIN_PRIORITY/new:Some.Component")
Note that when the destination queue is transactional, MSMQ ignores this attribute and uses a priority of 0.
PrivLevel
(long) determines the level to which outgoing messages are encrypted. This attribute can take on the following values:
MQMSG_PRIV_LEVEL_NONE
. The message is not encrypted at all (default).
MQMSG_PRIV_LEVEL_BODY
. The message body is encrypted using a 40-bit encryption technique.
MQMSG_PRIV_LEVEL_BODY_BASE
. The message body is encrypted using a 40-bit encryption technique (same as the preceding option).
MQMSG_PRIV_LEVEL_BODY_ENHANCED
. The message body is encrypted using a 128-bit encryption technique. This is the most secure of all the options.
Set b = GetObject("queue:PrivLevel=MQMSG_PRIV_LEVEL_BODY/new:Some.Component")
When any of the last three options are specified, the encryption technique to be used is determined by the EncryptAlgorithm
attribute.
Trace
(long) determines whether MSMQ generates report messages when and if it routes this message to a remote machine. Following are the values available for this option:
Set b = GetObject("queue:Trace=MQMSG_SEND_ROUTE_TO_REPORT_QUEUE/ new:Some.Component")
Again, this option only works in the context of an Active Directory setup.
3.142.213.250