I’m down in LA for Thanksgiving with Lauren‘s family for a few days of warm weather and sleeping in (Shawnie is a big fan of late morning wakeups). Yesterday we were put to work on a Lavoie traditional sidedish: cranberry salsa. Pretty easy to make with a food processor, and so so much better than your traditional cranberry sauce. Helene found the recipe in a magazine in 2000, and still had the clipping in her kitchen. Guaranteed to spice up your mild-mannered turkeys. Enjoy!
Monthly Archives: November 2005
Adapting Channel Shapes
As I implied in an earlier post, there’s a little more to the ServiceModel Channel Shapes then meets the eye. What I listed in the contract->shape mapping last week shows all the possibilities of what ServiceModel will request. However, it glosses over the process of how the channel requested is mapped to your service method. When you use ServiceModel, you get an extra layered channel at the top of your channel stack. The “Service Channel” has logic to normalize channel shapes into one-way and request reply patterns.
For example, let’s say you have method such as:
OperationContract
]void
Hello(string
name);Since this operation isn’t marked “IsOneWay=true”, it requires a request-reply channel. If you have a channel stack that only offers IRequestChannel, then Service Channel will use that shape directly. If your stack doesn’t offer IRequestChannel, but can create IDuplexSessionChannel, then ServiceModel will layer IRequestChannel on top of IDuplexSessionChannel (similar to how HTTP request reply is layered on top of a TCP connection).
With all this adaptation going on, how can you figure out what your stack will look like from a shape perspective? It’s not easy, but fortunately most users don’t need to worry about these details, they can simply trust that ServiceModel is creating a stack compatible with their endpoint. To decipher the magic, you need to understand what shapes each layer can offer, and under which conditions. For transports, it’s relatively straightforward, as they offer up fairly constant shapes (though they do occasionally vary based on configuration parameters). For layered channels you need to understand the mapping between what the layer beneath offers up, and how your layered channel can build upon those choices. That’s a topic for another time. For now, here are the choices for the transports:
Http
The most common mode for Http is IRequestChannel/IReplyChannel. In order to support 2-way sessions, we also define a one-way mapping for Http. You can request IOutputChannel/IInputChannel from our Http Transport. In one-way mode, we will return a “202 Accepted” response with an empty body immediately on receipt of the Http request. We send this response before we dispatch the received message so that we can emulate datagram to the best of our capabilities given the inherent request-response nature of Http. When using WsDualHttpBinding
you will see this behavior.
UPDATE (5/23/06, 9:22AM): In the latest V1 bits we’ve gotten crisper about our channel shapes. As Http is not natively one-way, it no longer supports IOutputChannel/IInputChannel. Rather, this “one-way over request-reply” functionality is provided by a layered binding element called OneWayBindingElement
. Details of how this mapping works are outlined here.
Tcp/Named Pipes
TCP and Named Pipes have the same capabilities and support two patterns: IRequestChannel/IReplyChannel, and IDuplexSessionChannel. IDuplexSessionChannel is the natural shape of a “connection” (socket/pipe) and is the shape we return by default. An IDuplexSessionChannel maps 1-1 to a connection. Fortunately IDuplexSessionChannel also offers the most flexibility to the layers above it. You can build any other pattern (IOuputChannel/IInputChannel, IRequestChannel/IReplyChannel, IOutputSessionChannel/IInputSessionChannel, and IRequestSessionChannel/IReplySessionChannel) on top of IDuplexSessionChannel. The one pragmatic restriction of IDuplexSessionChannel is that it does not support Message Streaming. If you have streaming enabled on your binding (TransferMode != TransferMode.Buffered), then we use the IRequestChannel/IReplyChannel shape. In streaming mode, we need to use connections in more of an HTTP-like manner. A connection is exclusively checked out for the lifetime of a request-reply pair, and returned to a connection pool when the request-reply pair has completed.
Msmq
Msmq not only supports IOutputChannel/IInputChannel, but they also support one-way session (IOutputSessionChannel/IInputSessionChannel) through a method they call “session-gram”. The way it works is that the Msmq Transport buffers all messages being sent on a sessionful channel, and when the session is closed they pass the entire session in a single Msmq message. This demarkated message is then received by the other queue and parsed into multiple messages.
Msmq Integration
As you might expect, when in “integration mode”, Msmq Transport offers up IOutputChannel/IInputChannel only.
I'm Feeling Lucky!
It only took 7 months, but I have finally succeeded in my page rank quest. MSN Search caught on to my site relevance a few months ago as the top hit for “Kenny Wolf”, but when I had last checked Google I was on page 7 (both Lauren and my Mom were higher ranked matches). I thought they might have something against Microsoft employees 🙂
Then last night I saw myself at the top of the list:
A touch of California in Seattle
At long last it looks like Washington State is getting on the no-smoking bandwagon. I-901 (Clean Indoor Air) was put to a vote, and with 94% of counties reporting, the current results have it passing by a wide margin (>63% in favor). Looks like I won’t need a special “bar jacket” anymore! 🙂
For those following along at home, the Secretary of State here has a great site for all election-related information.
WSE 3.0 available on MSDN
WSE 3.0 has just been released to the web. There are a number of great new features available, including compliance with the latest standards for secure web services, and guaranteed interoperability with WCF over http. You can also use my PDC sample to communicate with WSE 3.0 over TCP 🙂
Congrats to Mark, Hongmei, and the rest of the WSE team!
Sudafed difficulties
Probably due to the lovely Seattle November weather (i.e. 46 degress and rainy), I’m in the process of fighting a joyous head cold. To aid me in this process, I stopped by Rite Aid to pick up some Sudafed. All I could find was “Sudafed PE”. Finally I found a card for Sudafed to trade in at the pharmacy.
Turns out that while Sudafed is still non-presecription, a recent law requires you to have id checked so that you don’t run home and put it into your meth lab. God forbid you’re buying it because you have a cold, or want to make some jewelry.
You can get the non-Pseudoephedrine version on the shelf, but based on my 1 day side-by-side, I’ve found that phenylephrine is not nearly as effective.
The whole thing is reminiscent of the South Park cough syrup episode….
From Contract to Channel
When you create a client channel through ServiceModel, the shape of the channel is determined by various properties of your contract. Roughly the mapping is as follows:
OneWay | Request/Reply | Session | Callback | Channel |
Any | Any | No | Yes | IDuplexChannel |
Any | Any | No | Yes | IDuplexSesionChannel |
Any | Any | Yes | Yes | IDuplexSessionChannel |
Yes | Yes | No | No | IDuplexChannel |
Yes | Yes | No | No | IRequestChannel |
Yes | Yes | No | No | IDuplexSessionChannel |
Yes | Yes | Yes | No | IDuplexSessionChannel |
Yes | Yes | Yes | No | IRequestSessionChannel |
Yes | No | No | No | IOutputChannel |
Yes | No | No | No | IDuplexChannel |
Yes | No | No | No | IDuplexSessionChannel |
Yes | No | No | No | IRequestChannel |
Yes | No | Yes | No | IOutputSessionChannel |
Yes | No | Yes | No | IDuplexSessionChannel |
Yes | No | Yes | No | IRequestSessionChannel |
No | Yes | No | No | IRequestChannel |
No | Yes | No | No | IDuplexChannel |
No | Yes | No | No | IDuplexSessionChannel |
No | Yes | Yes | No | IRequestSessionChannel |
No | Yes | Yes | No | IDuplexSessionChannel |
ServiceModel also has internal adapters so that, for example, if your stack supports IOutputSessionChannel, then ServiceModel can adapt that channel to a desired IOutputChannel. More on this in a later post.