Windows Communication Foundation includes concepts which enable the developer to insist on reliably delivering messages in both directions. The mechanism is actually transport agnostic and allows messages to be flown reliably from client to service and replies from service to client.
Underneath, WS-ReliableMessaging (WS-RM) implementation is used. Click here for Microsoft's specification. Content is the same.
WS-RM is based on a concept of a message sequence. You can think of it in terms of a session, although it does not carry HTTP session semantics (remember, it's transport agnostic). A communication initiator (RM source) sends a <CreateSequence> element inside the message body to establish a RM sequence. Service side (RM destination) responds with either <CreateSequenceReponse> or <CreateSequenceRefused>, in cases where new sequence is not welcome.
After the sequence is initialized, there is an additional SOAP Header in messages. It identifies the message number being transferred. The following is a simple example of headers of the first two messages:
<S:Envelope> <S:Header> ... <wsrm:Sequence> <wsrm:Identifier>http://webservices.gama-system.com/RM/Service</wsrm:Identifier> <wsrm:MessageNumber>1</wsrm:MessageNumber> </wsrm:Sequence> </S:Header> ... <S:Body> ... </S:Body></S:Envelope>
<S:Envelope> <S:Header> ... <wsrm:Sequence> <wsrm:Identifier>http://webservices.gama-system.com/RM/Service</wsrm:Identifier> <wsrm:MessageNumber>2</wsrm:MessageNumber> </wsrm:Sequence> </S:Header> ... <S:Body> ... </S:Body></S:Envelope>
After all messages have been exchanged and acknowledged, the RM destination sends a <SequenceAcknowledgement> inside the body of the message. RM source (communication initiator) then tears down the sequence with a <TerminateSequence> message.
So, how can this specification be implemented in various technology stacks? Well, WCF implements reliable messaging using the in-memory message buffers. There is no durable reliable messaging support in WCF.
Here's how it works:
So, how do we go about enabling WS-RM and realizable delivery in WCF? Simple. Here's the config file:
<wsHttpBinding> <binding configurationName="myReliableBinding"> <reliableSession enabled="true" ordered="true" /> </binding></wsHttpBinding>
The <reliableSession> element has two attributes. The first one, enabled, enables reliable message delivery. The second one, ordered, enables in-order processing by the service model.
One has to acknowledge that the following is true for different WCF bindings:
basicHttpBinding - RM not supportedwsHttpBinding - RM supported, not defaultwsDualHttpBinding - RM implicitnetTcpBinding - RM supported, not default
There are a couple of options available for anyone using the custom binding, in regard to reliable messaging behavior:
There is some confusion in the wsHttpBinding's <reliableSession> config element. There's an enabled property in the Visual Studio config schema, which should not have any influence on reliable session establishment (and does not have a matching object model method/property). It does, however. There is a difference if you setup a reliable session by using a customBinding or wsHttpBinding.
I.e., here's the custom binding config:
<customHttpBinding> <binding configurationName="customReliableBinding"> <reliableSession ordered="true" /> </binding></customBinding>
This will enable reliable and ordered session support in any custom binding.
So, in general - WCF implementation of WS-ReliableMessaging gives you automatic message retries, duplicate detection, and ordering. It should be turned on for any multi-hop message paths, but can be very valuable even in high latency/packet loss network scenarios.
Update 2007-02-19
William Tay, a friend and distributed systems expert, replies with a terrific message exchange pattern for groking WS-RM specification. Don't walk, run.
Remember Me
The opinions expressed herein are my own personal opinions and do not represent my company's view in any way.
My views often change.
This blog is just a collection of bytes.
Copyright © 2003-2024Matevž Gačnik
E-mail