Exploring WCF Web Services
LANGUAGES: VB.NET | C#
TECHNOLOGIES: ASP.NET 2.0 | .NET 3.0 | WCF
IIS and WAS Hosting Architecture
How Requests to WCF Services Are Processed
By Michele Leroux Bustamante
This column explores the hosting model for WCF services in IIS 6 and IIS 7 with the Windows Activation Service (WAS). If you have questions about migrating your existing ASMX or WSE Web services to WCF, or questions regarding WCF as it relates to Web services, please send them to [email protected].
In earlier columns I gave you a crash course in creating WCF services that are hosted in IIS, and provided an overview of the Web service bindings available for configuring service endpoints. So, assuming you are familiar with creating WCF services and configuring endpoints for those services, you re probably ready to learn the hosting architecture for processing messages to services. In this column I ll explain the ServiceHost type; how message-based activation works for WCF services; review how IIS hosting works in general terms; and compare the hosting architecture for IIS 6 and IIS 7 with the Windows Activation Service (WAS).
For some background, read my earlier asp.netPRO articles ASP.NET and WCF: Meet Your New Web Service from the February 2007 issue, and Choosing the Right Web Services Binding from the March 2007 issue.
For those new to WCF, I ll provide a brief overview of the ServiceHost type, which is the center of the hosting story. You can host a WCF service in a Console application, a Windows application, an NT service, and IIS 6 or IIS 7 with the Windows Activation Service (WAS). In all cases, a ServiceHost type must be constructed to open the communication channel that processes messages to the service. That means initializing the ServiceHost with a service type so it knows which type to construct when a message arrives for a particular operation. You must also provide the ServiceHost with at least one endpoint describing:
- An address where clients can send messages. For Internet services this would be an HTTP address.
- A binding indicating the correct protocols to use to invoke the service. This would most likely be BasicHttpBinding or WSHttpBinding (per the March column).
- A service contract indicating the set of operations to make available at the specified address, over the specified protocols.
In a self-hosting environment (non-IIS) you might initialize the ServiceHost as follows:
ServiceHost host = new
, new WSHttpBinding(), "http://localhost:8000/HelloIndigoService");
// keep host alive until process shutdown
When Open is called, a communication channel is constructed for the endpoint, along with a message dispatcher. Clients use proxies to invoke service operations at a particular endpoint. When the message reaches the service model, a service object is constructed (if necessary) to handle the incoming message. Figure 1 illustrates this flow for a client communicating with a service hosted by a Windows service process.
Figure 1: Hosting model for a Windows service.
For IIS-hosted services the processing model is the same once the message reaches the service model; however, the client sends messages to a .svc endpoint instead, which in turn is associated with the ServiceHost and service type. Ultimately, the ServiceHost instance lives inside the WWW Worker Process (frequently called the ASP.NET Worker Process), as shown in Figure 2. In this case, no code is required to construct and open the ServiceHost type this is handled automatically through message-based activation (to be discussed). The .svc file indicates which service type should handle messages targeting the endpoint, as follows:
<% @ServiceHost Service="HelloIndigo.HelloIndigoService" %>
Figure 2: The IIS hosting model from a high level.
The point is that in both cases a ServiceHost instance must be constructed, associated with a service type, expose endpoints for that service type, and opened to create communication channels that process messages.
Services not hosted in IIS or WAS are called self-hosted services. This means developers must provide the process and the logic for constructing the ServiceHost. One drawback of self-hosting is that the host process must be running before requests to the service can be processed (so that the ServiceHost communication channels are ready to process messages). Another is that all messages are funneled to the same host process, so there is no automatic distribution of load or active health monitoring of available processes.
In the case of IIS and WAS hosting, the host process and ServiceHost instance are constructed (if necessary) in response to incoming messages known as message-based activation. From a high level, this means messages are queued waiting for an available worker process and ServiceHost instance to be constructed. In addition, one or more worker processes can be allocated to process messages, increasing throughput and scalability. There are variations in how this works for IIS 6 and IIS 7/WAS, but the high-level view consistent to both hosting environments is shown in Figure 3.
Figure 3: Request queues and message-based activation.
Message-based activation means that idle worker processes and associated ServiceHost instances can be released and reconstructed on demand preserving precious server resources.
IIS 6 Hosting
On a Windows Service 2003 machine you ll use IIS 6 to host HTTP endpoints for your WCF services. With IIS 6, requests first arrive at the http.sys kernel and are ultimately forwarded to a worker process where the ServiceHost lives. The WWW Service launches worker processes on demand to process requests and makes sure the request is sent to the appropriate request queue.
IIS 6 should be configured so that incoming requests for .svc files are forwarded to the aspnet_isapi.dll, just like other ASP.NET extensions such as .aspx and .asmx. That means requests to WCF services hosted in IIS are initially processed by the ASP.NET pipeline; however, service requests are ultimately handled by the service model, not by ASP.NET.
The ASP.NET pipeline looks for an HTTP handler to process each request but, along the way, HTTP modules that have been loaded into the application domain have the opportunity to interact with application events before and after the handler is invoked. In the case of WCF services, the System.ServiceModel.Activation namespace provides two such types:
- HttpModule. An IHttpModule implementation intended to hijack request processing for services, to send the request to the service model.
- HttpHandler. An IHttpHandler implementation that processes requests that are flowed through the traditional ASP.NET pipeline, if ASP.NET compatibility mode is enabled.
Figure 4 illustrates how IIS 6 processes requests up to the HttpModule and HttpHandler where the baton is passed to the service model.
Figure 4: How IIS 6 and ASP.NET process WCF service requests.
For the time being, I ll focus on the default processing model for WCF services (mixed transport mode). In this mode, although in theory requests for .svc files are destined for the configured HttpHandler type for processing, the HttpModule hooks the PostAuthenticateRequest application event and gets a chance early in the request cycle to redirect processing to the service model and bypass the ASP.NET pipeline. During PostAuthenticateRequest the HttpModule checks to see if ASP.NET compatibility is enabled; if not, the request is forwarded to the service model for processing via the HttpChannelListener from System.ServiceModel.Channels. As per Figure 4, the HttpHandler is never invoked in this case. In addition, when the module forwards requests to the service model, it releases the ASP.NET thread and transfers control to a thread from the WCF thread pool. That way, other ASP.NET requests can use the ASP.NET thread but more importantly, this allows WCF to consistently use its own thread pool configuration for all hosting environments.
As for ASP.NET compatibility mode, this feature allows WCF services to be processed by the traditional ASP.NET pipeline, whereby the HttpHandler will ultimately handle the request. In addition, this means that other configured HTTP modules can interact with the request throughout its lifecycle, such as those for caching, authentication, session, error handling, profiles, and others. Eventually the HttpHandler will facilitate processing the request (executing the operation) in the service model way, and operations will have access to the HttpContext among other features typical of ASP.NET applications. This mode is mainly targeting situations that require backward compatibility or migration of ASMX services.
IIS 7 and WAS Hosting Model
On Windows Longhorn Server machines you ll host your WCF services with Windows Activation Service ( WAS ). WAS is a process activation service installed with IIS 7 that decouples the activation architecture from IIS in order to support non-HTTP protocols, such as named pipes, TCP, and MSMQ. Like IIS 6.0, WAS also provides features for idle-time management, health monitoring, process recycling, and management tools for configuring application pools, among other things.
For HTTP requests, the hosting architecture is very similar to IIS 6:
- Requests are first received by the http.sys kernel.
- A new WAS service is responsible for configuring application pools, among other things.
- The WWW Service is responsible for activating application pools and requests queues to process incoming requests. In addition, this service has a new HTTP Listener Adapter that forwards requests to the HttpHandler to process the request (without the need for aspnet_isapi.dll).
- If ASP.NET compatibility mode is disabled, the HttpModule intercepts the request as discussed in the previous section.
- If ASP.NET compatibility mode is enabled, the HttpModule allows the request to proceed to the HttpHandler, as discussed.
The architecture of IIS 7 and WAS hosting is shown in Figure 5. Of course, ASP.NET is only involved if the service is hosted over HTTP.
Figure 5: How IIS 7, WAS, and ASP.NET process service requests.
There are a many benefits to this architecture, including:
- Requests no longer go through aspnet_isapi.dll for processing; instead, requests are directly forwarded to their associated handler.
- Many protocols, including custom (extensible) protocols, can be supported through WAS configuration. This allows you to learn a single model for all service deployments, even those behind the firewall.
- You can reap the rewards of improvements to the configuration and health monitoring features for worker processes.
At this point you should have a good idea how IIS, ASP.NET, and WCF interact to process requests to services exposed over HTTP. The nice thing is that you can allocate application pools for incoming requests to services, just as you would to ASP.NET application resources. It is in the transfer to the ASP.NET pipeline when the service model is involved to provide consistent processing for all services, regardless of their hosting environment. If you enable ASP.NET compatibility mode, you ll end up with a familiar ASMX model as far as the ASP.NET pipeline is concerned, but ideally you ll only use this for migration purposes.
WCF Home: http://wcf.netfx3.com
Learning WCF, O Reilly 2007: http://www.thatindigogirl.com (get all the book code here!)
Michele s blog: http://www.dasblonde.net
Michele Leroux Bustamante is Chief Architect at IDesign Inc., Microsoft Regional Director for San Diego, Microsoft MVP for Connected Systems, and a BEA Technical Director. At IDesign Michele provides training, mentoring, and high-end architecture consulting services, specializing in scalable and secure .NET architecture design, globalization, Web services, and interoperability with Java platforms. She is a board member for the International Association of Software Architects (IASA), a frequent conference presenter, conference chair of SD s Web Services and Web Development tracks, and a frequently published author. Michele recently completed the book, Learning WCF, published by O Reilly (book blog: http://www.thatindigogirl.com). Reach her at http://www.idesign.net or http://www.dasblonde.net.