- Windows services can start when the system starts, without requiring a user to log in to the machine.
- The Service Control Manager (SCM) provides an interface to manage service startup, restarts, and other run behaviors-a custom user interface isn't required.
- Services can restart after a failure, increasing overall availability.
To create a new Windows service application you can use the Windows Service application template. This generates a Windows service class that inherits ServiceBase and overrides its
OnStart() and
OnStop() methods. During
OnStart() you should initialize and open your ServiceHost instances. During
OnStop() you should close all ServiceHost instances and stop processing messages.
Listing 3 illustrates this implementation.
"One of the most important features IIS provides your WCF services is message-based activation."
|
|
To install the Windows service you should also provide an installer class. Use the installer class to initialize Service Control Manager (SCM) settings for the Windows service on installation. The following code shows an example of an installer class that provides a name and description for the Windows service, installs it to run under the identity NETWORKSERVICE, and then sets it to start automatically when the machine starts.
using System;
using System.ServiceProcess;
using System.ComponentModel;
using System.Configuration.Install;
[RunInstaller(true)]
public class WindowsServiceInstaller: Installer
{
public WindowsServiceInstaller()
{
ServiceProcessInstaller processInstaller = new
ServiceProcessInstaller();
ServiceInstaller serviceInstaller = new ServiceInstaller();
processInstaller.Account = ServiceAccount.NetworkService;
serviceInstaller.DisplayName ="WindowsServiceHost";
serviceInstaller.Description = "WCF service host.";
serviceInstaller.ServiceName="WindowsServiceHost";
serviceInstaller.StartType = ServiceStartMode.Automatic;
Installers.Add(processInstaller);
Installers.Add(serviceInstaller);
}
}
To deploy the service you can run this installer using the Installer Tool (installutil.exe) as follows:
installutil.exe WindowsServiceHost.exe
In theory, the service shouldn't stop unless something goes wrong, or an administrator explicitly stops it through the SCM. Fortunately in the former case, you can also configure the service to restart on failurea necessary feature for an unattended server machine.
Though the hosting code is much the same as in other self-host environments I've discussed, there are some special considerations for hosting WCF services in a Windows service:
- OnStart() must execute within 30 seconds or it will fail to start the service. If the startup code will take longer to execute, you can implement a timer to delegate longer running initialization after startup is complete. Simply initializing ServiceHost instances should fall within the 30-second timeframe.
- OnStart() will record exceptions in the Event Log, but uncaught exceptions after startup may not be recorded unless you explicitly catch the exception and record it.
- As with any hosting environment, the identity under which the Windows service runs will govern the Windows resources its services have access to at run time. Your deployment scripts can customize the account under which the service is configured if you don't want to hard-code this into the service installer.
On Windows Server 2003 machines the Windows service is the most reliable way to host WCF services for access over named pipe, TCP, or MSMQ protocols. In particular, this would apply to scenarios such as intranet applications, or distributed services behind the firewall as illustrated in
Figure 3.
 | |
| Figure 3: Hosting WCF services in a Windows service behind the firewall. |
IIS 6.0 Hosting
If you expose WCF services over the Internet using HTTP protocol on a Windows Server 2003 machine, IIS 6.0 makes for a much richer hosting environment than self-hosting. Unlike self-hosting, you don't need code to instantiate ServiceHost instances, but you can still use declarative configuration in the application's
web.config file. More importantly, IIS 6.0 provides other much-needed hosting features making your service more reliable, available, and scalable.
In this section I'll explain how IIS hosting works in general terms, discuss its distinct behaviors and added value, and provide you with an architectural overview of the IIS 6.0 hosting environment.
IIS Service Endpoints
When you host your services with any version of IIS you must provide at a minimum the following:
- An addressable Web Site or Virtual Directory for your service endpoints.
- A file with the extension .svc that will represent the ServiceHost instance.
- A service type that is linked to the .svc file for activation.
When you create a new Web Site project in Visual Studio, a WCF Service project template is provided. This template generates a project with a .svc endpoint, a sample service implementation, and a
web.config with the appropriate
<service> element to initialize the ServiceHost.
The .svc endpoint is the file that clients will address in their target URI to reach the service. It contains an
@ServiceHost directive that indicates the service type and if applicable the service source code in the
App_Code directory:
<% @ServiceHost Language=C# Debug="true"
Service="MyService"
CodeBehind="~/App_Code/Service.cs" %>
In reality, Visual Studio will compile your services into separate assemblies so your Web Site project must reference those assemblies and the .svc endpoint will reference the type only through the Service property of the
@ServiceHost directive. For example, this
Service.svc endpoint references the service type HelloIndigo.HelloIndigoService:
<% @ServiceHost
Service="HelloIndigo.HelloIndigoService" %>
The service type specified in the
@ServiceHost directive also tells the service model which
<service> section to use from the
web.config to initialize the ServiceHost instance. One of the distinctions between self-hosting and IIS hosting is that the Web Site or Virtual Directory for the application provides the base address. The
<service> section needn't provide an address for each endpoint since the .svc file is the endpoint:
<service
name="HelloIndigo.HelloIndigoService" >
<endpoint
contract="HelloIndigo.IHelloIndigoService"
binding="wsHttpBinding"/>
</service>
Clients address the service using the .svc endpoint, for example:
<client>
<endpoint
address="http://localhost/IISHost/Service.svc"
binding="wsHttpBinding"
contract="Client.localhost.HelloIndigoContract">
</endpoint>
</client>
In cases where you might want to expose multiple endpoints for the same .svc endpoint, you can use relative addressing. This example illustrates a case where clients can access the same
Service.svc endpoint using
BasicHttpBinding or
WSHttpBinding to support different Web service protocols. The
<endpoint> configuration for the service uses relative addressing, appending "/Soap11" and "/Soap12" to the endpoint address:
<service name="HelloIndigo.HelloIndigoService" >
<endpoint address="Soap11"
contract="HelloIndigo.IHelloIndigoService"
binding="basicHttpBinding"/>
<endpoint address="Soap12"
contract="HelloIndigo.IHelloIndigoService"
binding="wsHttpBinding"/>
</service>
Clients address each service endpoint in this way:
http://localhost/IISHost/Service.svc/Soap11
http://localhost/IISHost/Service.svc/Soap12
| Author's Note: For file-based Web sites, Visual Studio uses the ASP.NET Development Web Server instead of IIS. Endpoints function much the same as HTTP-based Web sites that are hosted in IIS, with the exception that a dynamically generated port assignment will exist in the endpoint address. For example, http://localhost:1260/FileBasedHost/Service.svc. |