Before I drill down into each of the smaller parts of the client-side channel stack implementation, I want to sketch out an overview of some of the moving parts of the channel layer. This picture is by no means complete, and I will probably revisit it several times over the next couple of posts. It should however provide you with a better understanding of what we are trying to accomplish in what part of the channel layer. And remember, this picture is a sketch and may not be 100% exact or correct.
What you see in the picture is the client-side of the WCF channel layer. I am trying to convey here that from the method call to the actual transport several things happen along the way.
First of all, when you call a service (or something else at the other end of the transport) you make a method invocation on a proxy. This might be
- a raw transparent proxy like we created in the first part of the series with a call to ChannelFactory<T>.CreateChannel.
- a ClientBase derived proxy, like the one you get when you use Add Service Reference (ASR). This proxy uses the same transparent proxy on the inside.
This method call is translated to a message object representing the method call. This message is dropped into a stack of channels that will massage the message every which way. The different channels in the stack all have their specific purpose, such as security, reliable sessions, or transport. The last channel in the stack is always the transport channel. The final transport channel will encode the message using an encoder and will serialize the bytes across the transport, whatever that may be (HTTP, MSMQ, TCP, UDP, email, …).
For Request/Reply message exchange patterns there will come a stream of bytes in response. The stream will be decoded by the message encoder, which gives another message object. The same holds true for duplex messaging, but for duplex the incoming request stream might be initiated by the service, without a previous message from us, the client. We will not encounter duplex/callback messages. Finally, the response message will be turned into the completion of the method call by yielding the return value and ref or out parameters. The method call returns to the caller. You may have guessed that this is for synchronous method calls on the proxy and you are absolutely correct. For now, we will leave asynchronous operations out of scope.
For each of the following posts I will highlight the area that we focus upon. Any feedback is welcome.