Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

MSMQ for .NET Developers (Part 1) : Page 4

MSMQ provides robust and easy-to-use messaging capabilities that let you send and receive messages between applications running on one machine, different machines, and even across the Internet, both synchronously and asynchronously. Unfortunately, MSMQ is notoriously underused. Find out how to get started with MSMQ and what you can do with it.


advertisement
The ResponseQueue Property
MSMQ provides an easy mechanism to correlate requests with responses, but—assuming this is a fault-tolerant solution running on multiple machines—how does the server know where to send response messages? You could make the response location a property of the message payload, incorporating it into the design of the message you are sending; however, proper separation of the payload from the delivery mechanism prohibits this form of mingling. To make this easier, MSMQ provides a ResponseQueue property on the Message object that you can use to provide the response location. Building on the scenario shown in the preceding code fragments, the client application would set the ResponseQueue property of the request message to specify the queue to which response messages should be sent. When the server is ready to send the response message, it opens the queue specified in the ResponseQueue property of the request message, and sends the response message to it.

When reading through the last code sample demonstrating the use of the CorrelationId property, did you wonder how the GetResponseQueue() function might be implemented? The following code sample shows how to implement the same code using the ResponseQueue property. It's an evolution of the previous code sample, demonstrating the client setting the ResponseQueue property of the request message, and the server using that ResponseQueue property as the destination queue for the response message. Note that this doesn't affect client processing of the response message.

Here's the client implementation for sending a request.

Private Sub SendRequestMessage(ByVal InternalState As String) Dim RequestQueue As System.Messaging.MessageQueue Dim ResponseQueue As System.Messaging.MessageQueue Dim RequestMessage As System.Messaging.Message Dim MessageId As String ' open request and response queues RequestQueue = GetRequestQueue() ResponseQueue = New MessageQueue(".\DevXResponseQueue") ' create message and set properties RequestMessage = New Message RequestMessage.Body = GetRequest(InternalState) RequestMessage.ResponseQueue = ResponseQueue MessageId = RequestMessage.Id() ' send message RequestQueue.Send(RequestMessage) ' store message state information StoreReqeust(InternalState, MessageId) End Sub

And here's the server implementation for processing the request.

Private Sub SendResponse(ByVal RequestMessage As Message, _ ByVal Response As String) Dim ResponseMessage As New System.Messaging.Message(Response) Dim ResponseQueue As System.Messaging.MessageQueue ' the response queue is retrieved from the request message ResponseQueue = RequestMessage.ResponseQueue ' set message properties ResponseMessage.CorrelationId = RequestMessage.Id ResponseMessage.Body = Response ' send the response message ResponseQueue.Send(ResponseMessage) End Sub

Finally, here's the client implementation for handling the response.



Private Sub NewMessageArrived(ByVal ResponseMessage As Message) Dim InternalState As String InternalState = LookupRequest(ResponseMessage.CorrelationId) ProcessResponse(InternalState, ResponseMessage) End Sub

The TimeToBeReceived and TimeToReachQueue Properties
In some instances, request messages are valid only for a limited time, when delayed processing of the messages could be detrimental, or at least superfluous. In a reservations system for example, requests for reservations after the actual reservation time would be unnecessary. Fortunately, MSMQ provides a facility for handling time-sensitive messages. By setting a time period for either the message to reach the destination queue (TimeToReachQueue) or for the message to be retrieved from the queue by the receiving application (TimeToBeReceived), you can be sure that messages will never be processed later than you intend.

When a message in a queue reaches the end of one of the two timeout periods, MSMQ either discards the message or moves it to the machine's dead-letter queue, which is an administrative queue created automatically by MSMQ. By default, MSMQ discards messages when they timeout, but you can force MSMQ to save the messages in the dead-letter queue on the machine where the message's timeout period expired by setting the UseDeadLetter property of the message to true.

While both properties can be set, in practice, there is probably little need to set both properties for a message. The TimeToReachQueue is useful when working with disconnected clients. It could be used to ensure that if the local machine cannot connect to the network, and hence cannot reach the remote destination queue, then the message should be abandoned. The TimeToBeReceived is probably more useful in that it encompasses both times (time to reach queue, and time to be retrieved from the queue). In most cases, it is likely that the amount of time the message sits waiting to be processed, whether in an outgoing queue on the sending machine or in the destination queue on the remote machine, will determine the fate of the message. In the event that you decide both timeouts should be used, be aware that the TimeToBeReceived time span should be longer than the TimeToReachQueue time span; otherwise, the TimeToReachQueue time span would never expire.

The code below demonstrates setting the TimeToBeReceived property of the message to 1 minute. Note that no other functions of the system change to support this feature.

' Client implementation for sending the request. Private Sub SendRequestMessage(ByVal InternalState As String) Dim RequestQueue As System.Messaging.MessageQueue Dim ResponseQueue As System.Messaging.MessageQueue Dim RequestMessage As System.Messaging.Message Dim MessageId As String ' open the request and response queues RequestQueue = GetRequestQueue() ResponseQueue = New MessageQueue(".\DevXResponseQueue") ' create the message and set message properties RequestMessage = New Message RequestMessage.Body = GetRequest(InternalState) RequestMessage.ResponseQueue = ResponseQueue RequestMessage.TimeToBeReceived = New TimeSpan(0, 1, 0) MessageId = RequestMessage.Id() ' send the message RequestQueue.Send(RequestMessage) ' store the message state details StoreReqeust(InternalState, MessageId) End Sub ' Server Implementation -- Processing the Reqeust Private Sub SendResponse(ByVal RequestMessage As Message, _ ByVal Response As String) Dim ResponseMessage As New System.Messaging.Message(Response) Dim ResponseQueue As System.Messaging.MessageQueue ' the response queue is retrieved from the request message ResponseQueue = RequestMessage.ResponseQueue ' set message properties ResponseMessage.CorrelationId = RequestMessage.Id ResponseMessage.Body = Response ' send the response message ResponseQueue.Send(ResponseMessage) End Sub ' Client Implementation -- Handling the Response Private Sub NewMessageArrived(ByVal ResponseMessage As Message) Dim InternalState As String InternalState = LookupRequest(ResponseMessage.CorrelationId) ProcessResponse(InternalState, ResponseMessage) End Sub



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date