Hervey and I just spent some face time discussing the implementation of the MSMQ transport and a very interesting thing came to light. First, I suggest you read Hervey’s blog entry on Channels that sets the stage for how the MSMQ transport is implemented. On the surface, things seem calm and pretty straight forward. In fact, the current MSMQ transport implements ISoapInputChannel, ISoapOutputChannel and ISoapTransport just as they’re written in Hervey’s blog – with a notable exception … I throw NotImplementedException for each of the ISoapChannel methods! Turns out that, while the MSMQ implementation is technically correct – and works – its not what’s intended in the larger scheme of endpoint references.
The challenge surfaces when you start discussing endpoint references. Granted, I’ve not spent much time at all trying to understand endpoint references – after all, the majority of the customers I’ve been working with have been focused on point-to-point SOAP over HTTP with no concerns yet for some of the advanced features of WS-Addressing – and I suggest that you read Herevey’s WS-Addresing archives for some good reading on the subject. From my discussion with Hervey, it is my understanding that it is possible for multiple endpoint references to point to the same URI. Why is this of concern? Well, in today’s SOAP over HTTP model, you can think of a one-to-one relationship between the URI (or, more commonly, the URL) and the service. With the introduction of endpoint references in WS-Addressing, it becomes possible for multiple listeners to be located at the same URI, and therefore it is necessary for the transport to properly route incoming messages to the channel that is registered against a given endpoint reference.
It bears calling out that an endpoint reference does not equal a URI, though if you look at the WSE 2.0 samples you’d be hard pressed to make this distinction. I pressed on this issue and it is understood there is a need to surface a set of samples that employ endpoint references to good effect.
So, what ends up being required is a way to read incoming messages from their source, determine the endpoint reference that cares about the particular message and then enqueue it to the channel that is associated with that endpoint reference. All of this is functionality you get by inheriting from SoapTransport, SoapInputChannel and SoapOutputChannel. As a result, I’m going to revisit the current implementation of the MSMQ transport this evening and take advantage of this infrastructure, thereby enabling the MSMQ transport to be endpoint reference aware.
Ultimately, you shouldn’t care too much about the internals of the WSE 2.0 transport model, as the general feeling is the majority of the population working with Web services don’t really care beyond the fact that it works. But if you want to understand what’s going on under the hood or be able to write your own transport, it’s important to understand some of the subtleties that are not immediately noticeable.