I mentioned in an earlier post how the Service Model Runtime normalizes different channel shapes based on the requirements of your OperationContract. One of the adaptations the Service Model Runtime provides is the ability to use one-way methods over IRequestChannel
and IReplyChannel
.
For example, let’s say you have method such as:
OperationContract
(IsOneWay=true
]void
SendUpdate(string
update);If you want to expose this method over BasicHttpBinding
, how does that work? HTTP is fundamentally request-reply based, and as such offers up only IRequestChannel
and IReplyChannel
.
To address this scenario, part of the model for request-reply is a paradigm whereby a channel can optionally support “null” responses. This is exposed through the programming model by calling IRequestContext
.[Begin]Reply(
null
)
. As an additional convenience, if you call IRequestContext
.Close()
without having sent a reply we will call Reply(
null
)
on your behalf.
HTTP signals a “null” response on the wire by sending a “202 Accepted” with no entity body. Note that for interop purposes we are lax on the client and allow any 200-level response without an entity body to signal null response. TCP/Pipes send a .Net Framing ACK with no entity body. A message-level protocol for request reply can designate a particular schema/action for an “ACK Message” to signal a null response.
On the client you should check for a null
return value from IRequestChannel
.SendRequest()
. For example:
Message
reply = requestChannel.SendRequest(request);if
(reply ==null
) {Console
.WriteLine("Called a one-way method."); }else
{Console
.WriteLine("Called a two-way method."); }
ServiceModel, as well as our forthcoming OneWayBindingElement
leverage the “null” response in order to achieve mapping request-response message exchanges to one-way.
Pingback: kennyw.com » Blog Archive » The effect of IsOneWay on Operations
Pingback: kennyw.com » Blog Archive » On the Wire with channel.Open()/Close()