Dışarıya aktar (0) Yazdır
Tümünü Genişlet
EN
Bu içerik dilinizde bulunmamaktadır ancak İngilizce sürümüne buradan bakabilirsiniz.

Hosting WCF Services with Service Bus Endpoints on IIS

Updated: January 21, 2014

Author: Santosh Chandwani

Reviewer: Seth Manheim

This topic describes how to host WCF services with Windows Azure Service Bus endpoints on Internet Information Services (IIS) version 7.5, which is included in Windows Server 2008 R2 and Windows 7. Windows Azure Service Bus provides connectivity and messaging features required by applications running on the Windows Azure platform or in hybrid scenarios.This topic focuses on the steps required to host services that were developed using the Windows Azure SDK 1.5 or later, on IIS.

An Overview of Windows Azure Service Bus

Windows Azure Service Bus provides a hosted, secure, and widely available infrastructure for widespread communication, large-scale event distribution, naming, and service publishing. Service Bus provides connectivity options for WCF and other service endpoints, including REST endpoints that would otherwise be difficult or impossible to reach. Endpoints can be located behind network address translation (NAT) boundaries, bound to frequently-changing, dynamically-assigned IP addresses, or both.

Service Bus provides both “relayed” and “brokered” messaging capabilities. In the relayed messaging pattern, the relay service supports direct one-way messaging, request/response messaging, full-duplex messaging, and peer-to-peer messaging. Brokered messaging provides durable, asynchronous messaging components such as queues, topics, and subscriptions, with features that support publish-subscribe and temporal decoupling: senders and receivers do not have to be online at the same time; the messaging infrastructure reliably stores messages until the receiving party is ready to receive them. These patterns are important to applications migrating to the Windows Azure platform.

The Service Bus tools included with the Windows Azure SDK simplify integration of on-premises .NET applications with the service. The SDK provides seamless integration with the Windows Communication Foundation (WCF) and other Microsoft technologies to leverage existing developer skill sets as much as possible. The Service Bus SDK includes Service Bus bindings for various HTTP and net.TCP relay bindings, and a messaging binding for brokered messaging. You can find the full list of Service Bus “relay” bindings at Service Bus Bindings and the messaging binding at NetMessagingBinding.

Although these services have been designed to provide a first-class .NET developer experience, it is important to note that they each provide interfaces based on industry-standard protocols, making it possible for applications that run on any platform to integrate with them through REST, SOAP, or WS-* protocols. There are also Service Bus SDKs for Java and Ruby available for download here.

Challenges in Activating Services Hosted on IIS

The main challenge in hosting a WCF service using Service Bus bindings on IIS is related to activation. By default, IIS initializes a web application when the first request is received.

However, for the on-premises WCF service with a Service Bus relay binding to start receiving messages from Service Bus in the cloud, the on-premises service has to open an outbound port and create a bidirectional socket for communication. It connects to Service Bus, authenticates itself, and starts listening to messages before the client sends its requests. The relay service sends messages to the on-premises service through the bidirectional socket already in place.

Similarly, a “messaging” binding provides an automatic messaging pump that pulls messages from a queue or a subscription, and is integrated into the WCF ReceiveContext mechanism. This binding also has to initiate an outbound connection to Service Bus in the cloud, and authenticate itself before the message pump is activated.

Because IIS and the Windows Activation Service (WAS) rely on message-based activation, by default the web applications hosted in IIS/WAS are initialized only after the first request comes in. Therefore, the usual IIS/WAS message-based activation does not work for WCF services with Service Bus bindings, because these bindings must first establish an outgoing connection to the service in order to receive messages. This requirement means that when hosted on IIS, such WCF services must be explicitly initialized, or they require alternate mechanisms to automatically initialize the application. This topic describes two methods to automatically initialize the application using the ASP.NET Auto-Start mechanism and the Microsoft AppFabric Auto-Start capability. Alternatively, you can use an NT service as a host.

Integration with the HTTP Pipeline

Service Bus bindings that use HTTP are not integrated with the managed/unmanaged HTTP pipelines. Thus, ASP.NET compatibility is broken and certain scenarios, such as sharing session state between the service and an ASP.NET application hosted in the same application domain, do not work for WCF services with Service Bus bindings.

Developing WCF Services That Use Service Bus Endpoints

To build WCF services with Service Bus endpoints, see the section Developing Applications that use the Service Bus on MSDN. A number of sample applicationsare available.

Consider a simple WCF Echo service that has a standard WCF webHttpBinding endpoint. A code snippet for the service appears as follows:

public class WebHttpService : IWebHttpService
{
    public string Echo(string value)
    {
        return string.Format("Echoing: ‘{0}’", value);
    }
}

The next step is to update the service to use two Service Bus endpoints that use the webHttpRelayBinding binding. You can host this service in IIS to benefit from the IIS/WAS hosting capabilities.

Web.config Update

The following example adds the endpoint information to the Services section of the Web.config file. In this snippet, replace the EchoService service namespace, sb-test service name information, and issuer information with your service namespace and service.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.serviceModel>
  <services>
    <clear />
    <service behaviorConfiguration="MyServiceTypeBehavior" 
      name="Microsoft.ServiceBus.Samples.WebHttpService">
      <endpoint address="https://sb-test.servicebus.windows.net/WebHttpService/"
      behaviorConfiguration="sharedSecretClientCredentials" 
binding="webHttpRelayBinding"
      bindingConfiguration="WebHttpRelayEndpointConfig" 
name="RelayEndpoint"
      contract="Microsoft.ServiceBus.Samples.IWebHttpService" />
    </service>
  </services>

    <bindings>
      <webHttpRelayBinding>
        <binding name="WebHttpRelayEndpointConfig">
          <security relayClientAuthenticationType="None" />
        </binding>
      </webHttpRelayBinding>
    </bindings>

    <behaviors>
        <!-- Service Bus endpoint behavior-->
        <endpointBehaviors>
          <behavior name="sharedSecretClientCredentials">
            <webHttp/>
            <transportClientEndpointBehavior credentialType="SharedSecret">
              <clientCredentials>
                <sharedSecret issuerName="ISSUER_NAME" issuerSecret="ISSUER_KEY" />
              </clientCredentials>
            </transportClientEndpointBehavior>
          </behavior>
        </endpointBehaviors>
   </behaviors>
  </system.serviceModel>

ServiceRegistry Settings Behavior Extensions

By default, services published to the Service Bus relay are “cloaked” and not visible in the Service Registry ATOM feed. For details, see the section Discovering and Exposing a Service Bus Service. Note that this step to make the service visible in the Service Registry feed is optional.

In order to set the discoverability policy to “Public,” first create a custom BehaviorExtensionElement for ServiceRegisterySettings in the system.serviceModel section of the Web.config file.

<system.serviceModel>
  <extensions>
    <behaviorExtensions>
<add name="ServiceRegistrySettings"
type="Microsoft.ServiceBus.Samples.MyServiceRegistrySettingsElement, WebHttpService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </behaviorExtensions>
  </extensions>

The next step is to create a class called MyServiceRegistrySettingsElement that inherits from BehaviorExtensionElement. For example:

public class MyServiceRegistrySettingsElement : BehaviorExtensionElement
{
    public override Type BehaviorType
    {
        get { return typeof(ServiceRegistrySettings); }
    }

    protected override object CreateBehavior()
    {
        return new ServiceRegistrySettings() 
{ DiscoveryMode = this.DiscoveryMode, 
  DisplayName = this.DisplayName };
    }

    [ConfigurationProperty("discoveryMode", DefaultValue = DiscoveryType.Public)]
    public DiscoveryType DiscoveryMode
    {
        get { return (DiscoveryType)this["discoveryMode"]; }
        set { this["discoveryMode"] = value; }
    }

    [ConfigurationProperty("displayName")]
    public string DisplayName
    {
        get { return (string)this["displayName"]; }
        set { this["displayName"] = value; }
    }
}

Enabling Diagnostic Tracing for the Service

To optionally enable diagnostic tracing for the WCF service, you can enable a trace listener. To do this, add the following section to the Web.config file:

<system.diagnostics>
  <sources>
    <source name="System.ServiceModel" switchValue="Warning">
      <listeners>
        <add name="traceListener"
             type="System.Diagnostics.XmlWriterTraceListener" 
             initializeData="C:\Log\Traces.svclog" />
      </listeners>
    </source>
  </sources>
</system.diagnostics>

Note that the folder in which you want the traces to be emitted (“C:\Log” in the above snippet) will not be created automatically; it must exist.

Hosting WCF Services with Service Bus Endpoints on IIS 7.5

You can host WCF services with Service Bus endpoints on IIS by leveraging the ASP.NET Auto-Start feature for initialization. The Auto-Start feature enables the initialization of web applications without having to wait for an external request. This feature proactively loads and initializes any dependencies such as opening database connections, loading modules, and so on. It preloads the worker processes at the start of the web server before the first request arrives. It also allows for recovery from faults, and for custom code plug-ins to perform advanced initialization.

There are three changes that should be made to leverage the ASP.NET auto-start capability:

  • Application pool configuration

  • Adding a custom auto-start provider

  • Using a custom service host factory for fault recovery

Application Pool Configuration

In order to leverage the Auto-Start feature, host the WCF service in a virtual application which in turn is associated with an application pool targeting the .NET runtime version 4.0.

HostingWCFServices1

Next, the IIS Application Pool must be configured for Auto-Start. This can be done by editing the applicationHost.config file. The startMode attribute for the application pool used must be set to AlwaysRunning in the configuration file at %windir%\System32\inetsrv\config\applicationHost.config.

In this example, the application pool is “WebHttpServicePool”:

add name=" WebHttpServicePool" autoStart=“true” managedRuntimeVersion="v4.0" startMode="AlwaysRunning" />

Note that an IIS application pool can host multiple virtual applications. In this example, the application is “/WebHttpService”. You can configure this by adding the serviceAutoStartEnabled and serviceAutoStartProvider attributes to the application entry in the applicationHost.config file. For example:

<sites>
    <site name="Default Web Site" id="1">
        <application path="/WebHttpService" 
                     applicationPool="WebHttpServicePool" 
                     serviceAutoStartEnabled="true" serviceAutoStartProvider="AutoStartWebHttpService">
             <virtualDirectory path="/"
                     physicalPath="C:\inetpub\WebHttpService" />
        </application>
    </site>
</sites>

Note that in IIS, if the application pool is explicitly stopped for any reason, the serviceAutoStartEnabled attribute is reset to false. In this case, you may have to set it back to true to restore this functionality.

Adding a Custom AutoStart Provider for the Service

The serviceAutoStartProvider attribute referenced in the previous step refers to a custom class that encapsulates the start-up logic for the application. The ServiceAutoStart class is automatically invoked when the application pool and the application are preloaded (before any external web requests are received for the application). The ServiceAutoStart class is automatically invoked to start the service host which in turn registers the Service Bus endpoint to the cloud. When the Preload method of the class is invoked, it ensures that the service host is activated through a call to ServiceHostingEnvironment.EnsureServiceAvailable().

In this example, the ServiceAutoStart class is part of the Microsoft.ServiceBus.Samples assembly. The applicationHost.config file must be updated as follows:

<system.applicationHost>

...
<serviceAutoStartProviders>
    <add name="AutoStartWebHttpService" 
         type="Microsoft.ServiceBus.Samples.AutoStartWebHttpService, WebHttpService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</serviceAutoStartProviders>

</system.applicationHost>

The code for the AutoStartWebHttpService class is as shown below.

public class AutoStartWebHttpService : System.Web.Hosting.IProcessHostPreloadClient
{
    public void Preload(string[] parameters)
    {
        bool isServceActivated = false;
        int attempts = 0;
        while (!isServceActivated && (attempts <10))
        {
            Thread.Sleep(1 * 1000);
            try
            {
                string virtualPath = "/WebHttpService/WebHttpService.svc";
                ServiceHostingEnvironment.EnsureServiceAvailable(virtualPath);
                isServceActivated = true;
            }
            catch (Exception exception)
            {
                attempts++;
                //continue on these exceptions, otherwise fail fast
                if (exception is EndpointNotFoundException
                    || exception is ServiceActivationException
                    || exception is ArgumentException)
                {
                    //log
                }
                else
                {
                    throw;
                }
            }
        }
    }
}

Note that in the above sample, virtualPath should be updated as appropriate for the application.

Using a Custom Service Host Factory for Recovery from Faults

If the WCF service host fails, IIS/WAS cannot recreate the host object. In this case, you can recycle the app pool manually.

In order to recreate the host object automatically in a fault scenario, you can use the custom service host factory pattern of WCF. See Custom Service Host for details.

You can add the custom service host factory class to the WCF service. For example:

public class ServiceHostFactoryWebHttpService : ServiceHostFactory
{
    Type incomingServiceType;
    Uri[] incomingBaseAddresses;

    private void OnServiceHostFaulted(object sender, EventArgs e)
    {
        ICommunicationObject faultedHost = (ICommunicationObject) sender;
        faultedHost.Abort();

        ServiceHost host = new ServiceHost(this.incomingServiceType, this.incomingBaseAddresses);
        host.Faulted += this.OnServiceHostFaulted;

        // Sleep to allow time for resource to come back – may require over 10s 
        // for remote services. Without wait/retry logic, process may throw
        // StackOverflow exception if resource is unavailable for an extended 
        // period of time.
        System.Threading.Thread.Sleep(TimeSpan.FromSeconds(10)); 

        host.Open();
    }

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        this.incomingServiceType = serviceType;
        this.incomingBaseAddresses = baseAddresses;
        ServiceHost host = new ServiceHost(serviceType, baseAddresses);
        host.Faulted += this.OnServiceHostFaulted; 
        return host;
    }
}

The Thread.Sleep code in this snippet is illustrative. For production services, use appropriate wait/retry logic.

To invoke the service host factory, you can add the Factory attribute to the .svc file for the WCF service. In this case, it is the WebHttpService.svc file.

<%@ServiceHost language="C#" Debug="true" 
    Service="EchoServiceMicrosoft.ServiceBus.Samples.WebHttpService" 
    Factory="Microsoft.ServiceBus.Samples.ServiceHostFactoryWebHttpService" 
    CodeBehind="WebHttpService.svc.cs" %>

Hosting WCF Services with Service Bus Endpoints in Microsoft AppFabric

Microsoft AppFabric 1.1 for Windows Server is a set of IIS extensions that provides the ability to easily configure, manage and monitor WCF and WF applications on IIS. See Microsoft AppFabric 1.1 for Windows Server for an overview of Microsoft AppFabric 1.1 for Windows Server and its capabilities.

This section describes the steps to use Microsoft AppFabric features for WCF services with Service Bus endpoints.

Adding Service Bus Schema for Microsoft.Web.Administration

Microsoft AppFabric uses the Microsoft.Web.Administration (MWA) APIs to read and write the configuration schema. MWA APIs use schemas stored in %SystemRoot%\System32\inetsrv\config\schema. Because the Web.config file for the service in this example contains a custom endpoint configuration for Service Bus bindings, you must add the MWA schema for the Service Bus endpoints (link to ServiceBus_schema.xml) and place it in the MWA schema folder mentioned previously. MWA automatically picks up the schema and parses the Service Bus-specific configuration correctly.

Configuring auto-start

The Microsoft AppFabric auto-start feature for WCF and WF services builds on the ASP.NET 4 auto-start feature. It enables the service to be started automatically when IIS is restarted or if the application pool recycles.

In IIS Manager, select the application (in this example, WebHttpService) and click Configure… below the Manage WCF and WF Services section of the Actions pane on the right-hand side.

HostingWCFServices2

This selection displays the Configure WCF and WF for Application dialog. Click Auto-Start on the left-hand menu, then click Enabled (all services auto-start). Click Yes to set the startMode to AlwaysRunning for the application pool.

HostingWCFServices3

Fault Recovery Using a Custom Service Host Factory

For automatic recovery and to recreate the host object in a fault scenario, use the custom service host factory pattern of WCF mentioned in the section Using a Custom Service Host Factory for Recovery from Faults. The use of the custom service host factory pattern of WCF is required for WCF services with Service Bus endpoints that are hosted on Microsoft AppFabric.

Summary

Windows Azure Service Bus supports bindings for its relay and messaging functionality, making it easy to access Service Bus in the cloud from WCF services. This article documented a set of configuration updates required for hosting such WCF services on IIS. The article also described the use of the custom service host factory WCF pattern that is required for automatic recovery from faults.

Topluluk İçeriği

Show:
© 2014 Microsoft