Author Archives: kenny

Beyond the .asmx/.svc suffix: Multiple Endpoints

One of the key improvements in WCF is the concept of multiple “endpoints” at a Service. Last week (when I was offsite with a customer) I had an interesting revelation. While we cover the “ABCs” of Indigo (Address + Binding + Contract == Endpoint) in every introductory talk, many users don’t fully grasp the flexibility multiple endpoint support offers. This is most acute with regards to hosting in IIS, when multiple endpoint support involves “URI space beyond the file”.

For example, let’s say I have an Image Download Service hosted at image.svc. For interop purposes I expose a BasicHttp endpoint. I also add a second endpoint that uses a binary encoding instead of text. I provide a relative address of “binary” to this endpoint for addressing purposes. In this case my interop endpoint is exposed as:
http://kennyw.com/vdir/image.svc

And the binary endpoint is addressible as:
http://kennyw.com/vdir/image.svc/binary

Yes, that’s “/binary” after the filename.

The relevant piece of config for such as service (assuming you have a “binaryHttpBinding” defined in your bindings section) looks like:

<system.serviceModel>
 <services>
  <service name="Microsoft.ServiceModel.Samples.ImageService">
    <endpoint address=""
              binding="basicHttpBinding"
              contract="Microsoft.ServiceModel.Samples.IImageService" />

    <endpoint address="binary"
              binding="binaryHttpBinding"
              contract="Microsoft.ServiceModel.Samples.IImageService" />
  </service>
 </services>
</system.servicemodel>

Building a "Composite" Transport

I’ve often written about how to write custom channels; transports in particular. In all of the examples I’ve given, the same transport is used for both sending and receiving messages (i.e. HTTP out, HTTP in). This parallelism fails in certain scenarios. For example, WS-Discovery defines a pattern where you send out a UDP Multicast probe (a broadcast request to find a peer), and expect (one or more) HTTP unicast responses back.

Constructing a binding for this scenario requires three pieces:

  1. An outgoing transport
  2. An incoming transport
  3. A correlation mechanism to tie the request to the response

For the transports, you need a BindingElement that returns the outgoing transport from BuildChannelFactory and the incoming transport from BuildChannelListener. One way of doing this is with a CompositeTransportBindingElement. A CompositeTransportBindingElement uses two bindings to build its runtime components. For example, you can pass in a binding that consists of OneWayBindingElement + HttpTransportBindingElement. Or one that contains UdpBindingElement.

For correlation, if you add CompositeDuplexBindingElement to the stack, you can configure a ClientBaseAddress and Service Model will provide correlation using WS-Addressing. You could also provide correlation yourself (which is actually a good topic for later this week :))

The relevant pieces of CompositeTransportBindingElement (posted here) are:

class CompositeTransportBindingElement
        : TransportBindingElement
{
    Binding channelBinding;
    Binding listenerBinding;

    public CompositeTransportBindingElement(
        Binding channelBinding,
        Binding listenerBinding)
    {
        this.channelBinding = channelBinding;
        this.listenerBinding = listenerBinding;
    }

    public override IChannelFactory<TChannel>
             BuildChannelFactory<TChannel>(BindingContext context)
    {
        return channelBinding.BuildChannelFactory<TChannel>(
            context.BindingParameters);
    }

    public override IChannelListener<TChannel>
            BuildChannelListener<TChannel>(BindingContext context)
    {
        return listenerBinding.BuildChannelListener<TChannel>(
            context.ListenUriBaseAddress,
            context.ListenUriRelativeAddress,
            context.ListenUriMode,
            context.BindingParameters);
    }
}

Using Overloaded Operations in your ServiceContract

A common programming paradigm with objects is the use of overloaded methods. That is, multiple methods with the same name, but different parameters. In reality though, this paradigm is syntactic sugar on top of a compiler that is generating different fully-qualified names.

It may be that you’ve done your service-oriented scrub and decided you want to expose two overloaded methods. From a service-orientation perspective, the compiler isn’t adding extra qualifications to differentiate the methods. Our default action generation is based on the operation name, which defaults to the name of your method. As such, in order for a client (and our dispatcher) to distinguish between multiple overloaded methods, you need to provide them with unique names. For example:

[ServiceContract]
interface ICalculator
{

[OperationContract(Name= "Add_Int")]
int Add(int x, int y);

[OperationContract(Name= "Add_Long")]
long Add(long x, long y);

}

Ponti Seafood Grill (Seattle, WA)

Rating:

My first experience at Ponti Seafood Grill was exactly nine months ago. Lauren and I had finalized our wedding date just in time to be able to celebrate our “-1 year anniversary” (yes, we are a geek couple). I had been meaning to try Ponti for years (since it had first been recommended to me in 1998), and my first experience was a memorable one. We were seated on the patio overlooking the ship canal, and immersed ourselves in the casually romantic ambience. The shrimp appetizer, seared scallop angel hair pasta, and chocolate dessert were all fantastic. Overall the evening was a positive indicator for future anniversaries 🙂

Grilled Alaskan Troll Caught King SalmonFast forward nine months. DeAnn has a college friend in town and wanted to show him a good seafood restaurant that didn’t break the bank. Armed with our Prime card 2 for 1 benefit, Lauren and I suggested Ponti. A quick check on OpenTable showed availability at 7:45PM for our party. We locked in the slot, and showed up promptly to enjoy our dinner.

Unfortunately it was to be almost an hour and a half before we were able to enjoy our meal. The hostess had horribly overbooked the restaurant and there were 3 large (>6 person) parties in addition to our own that all waited 30-40 minutes to be seated. This is when the darker side of Ponti hospitality reared its ugly head. The hostess told us “just a few minutes” enough to make me think we were living the Seinfeld Chinese Restaurant episode. After she parked us in the bar area, the waitress asked for our drink order. When it was apparent we weren’t ordering drinks, she walked off in a huff and only returned with dirty looks that I can only assume meant we were taking up a table she could be making tips from. It seems that my group of grad students who had come to eat seafood, not sit in a holding pattern should be expected to pay for this “privilege”? Their top marks for service were getting more tarnished by the minute.

When we were finally seated around 8:20PM the waiter was pleasant and helpful. We ordered a few appetizers and our entrees, and then proceeded to catch up with DeAnn’s friends. Fortunately we had plenty of conversation to pass the time and no one was ravenously hungry, as our appetizers were treated as side dishes by the staff. All of our food arrived together at 9:15PM.

The food aspect of Ponti’s remained true to my fond memories. My compatriots encouraged roaming forks, so I was able to sample an assortment of dishes. The dungeness crab spring rolls were flaky, generous with crab, and complemented with a smooth red curry & cilantro aioli. The cajun barbeque prawns were reminiscent of New Orleans, and were still enjoyable at room temperature (they had sadly suffered from a disconnect between the kitchen and our inattentive waitstaff).

Soft shell crab is in season, and if you’ve never experienced the act of consuming an entire crab from head to claw, the Garlic Tempura Soft Shell Crab at Ponti is a great introduction.

Grilled Hawaiian Ahi TunaPonti smokes their Black Cod in house, and if you enjoy smoky flavor with smooth, slightly-oily black cod texture then this is the dish for you. The Grilled Ahi is a variation of the Asian-fusion seared Ahi dish that is popular around town. The Ahi steak is enormously thick and fresh. It is served with a tasty medley of wasabi, soy and sriracha slaw. I personally prefer searing to grilling for this dish, but this is a fine sample of the grilled variation.

Overall the food was great with service that could use a stern reprimand. I’ll be on the phone providing fodder for such this week, and hopefully your service experience will be more on par with the food!

Ponti Seafood Grill
3014 3rd Ave North
Seattle, WA 98109
206-284-3000

Daily: 5:00PM-close (Dinner only)

IReplyChannel and "null" replies

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.

Shanghai Garden (Seattle, WA)

Rating:

There is a plethora of great Asian cuisine in Seattle. There are (almost) as many good Thai restaurants as there are Starbucks. When it comes to Chinese food though, it’s slim pickings in this city. Fortunately there are a handful of standouts in this category, with Shanghai Garden topping the list.

My buddy Dan set up shop for his new startup Ontela in Pioneer Square. His office is in convenient proximity to the I-District. So when Lauren and I were invited to join him for dinner tonight, I had to propose Shanghai Garden. We sampled three of my favorite dishes.

First, a favorite of Vidya‘s and Leslie’s: Eggplant and Hot Garlic Sauce (with pork), but without the pork so that it can be enjoyed by the vegetarians.

Eggplant and Hot Garlic Sauce

Next up, a dish I often use to judge Chinese restaurants on my first visit: Chicken in Black Bean Sauce. Shanghai Garden has consistenly excelled on this one. No matter how sated you become, you will be tempted to squeeze in just “one more bite” 🙂

Chicken in Black Bean Sauce

Finally, a specialty of the house: Hand Shaven Barley Green Noodles with your choice of meat/veggies. They are trumpeted as a “healthy” dish: if all “healthy” food tasted this good life would be easy. For those that get queasy when dealing with green food, they also have hand shaven “regular” noodles (which are more of a light gold, “normal noodle” color). You’d be missing out on a unique pleasure though!

Hand Shaven Barley Green Noodles

For those readers living on the Eastside, there is another Shanghai Garden branch in Issaquah.

Shanghai Garden
524 6th Ave South
Seattle, WA 98104
206-625-1688

Mon-Th: 11:00AM-9:30PM
Fri-Sat: 10:00AM-10:30PM
Sun: 10:00AM-9:30PM
(Lunch and Dinner)

Building a "client-side" Listener

I wrote earlier about how to write a Service that listens on any free port. If you are programming at the Channel/Binding layer directly, the easiest way to autogenerate a ListenUri is to call the following method on your Binding:

public IChannelListener<TChannel> BuildChannelListener<TChannel>(params object[] parameters)

For example: myListener = myBinding.BuildChannelListener<IInputChannel>();

The base class will expand this call out to create a Listener using the scheme from the binding, the hostname of the machine, and ListenUriMode.Unique to generate the rest of the ListenUri:

UriBuilder listenUriBuilder = new UriBuilder(this.Scheme, machineName);

return this.BuildChannelListener<TChannel>(listenUriBuilder.Uri, string.Empty, ListenUriMode.Unique, parameters);

Flying Fish (Seattle, WA)

Rating:

I have had a long tumultuous relationship with the Flying Fish. In 1996 as an interview candidate, I first set foot in the bar on a cold February night. The friendly bartender was shutting down but directed me to Minnie’s for some late-night grub. In 1998 I had the first of many great dinners there with my Dad. Then in 2001 an offensive maitre’d turned me off to the restaurant for awhile (I found out later he was generally disliked and fired not long after my encounter). LL and I had considered the Flying Fish in January as a location for dinner, but the recent citysearch reviews gave us pause. As we found out last night we should have ignored our trepidations, for the food was as good as ever.

Thai Crab CakeAfter a Cinco de Mayo happy hour at the Apartment, the munchies called and we rolled the dice (and scored) on a table at the Flying Fish. They market themselves as a destination for both “quick bites” and “doing the town”. In the past I’ve only considered the Fish as an option for a nice dinner out. Last night reminded me that they are equially viable as a venue for an informal, light meal.

We started with their Thai Crab Cake. As our waiter noted, the only thing “Thai” about it is the lemongrass aioli drizzled over the cake. It adds a nice overtone to a crab cake which can rival the best Seattle has to offer.

When I come to the Flying Fish with a group I salivate over the platters, either the Whole Fried Rockfish or the Salt & Pepper Crabs. Neither of these dishes are viable for two, so last night we ventured for a new platter: Grilled Fish Tacos. These are not your average fish tacos. The handmade tortillas are tiny, but the innards taste equally scrumptious on your fork as they do in the tortillas. While I expected high quality fish, I was pleasantly surprised by the tasty salsa and guacamole.
Fish Tacos

While I miss the rockshrimp springrolls (Christine, please bring them back!), the Flying Fish is still flying high with awesome food, friendly service, and classic Seattle atmosphere.

Flying Fish
2234 1st Ave (at Bell)
Seattle, WA 98121
206-728-8595

M-F: 11:30AM-2:00PM (Lunch)
Daily: 5:00PM-2:00AM (Dinner + Late-night Menu)