WCF and Hosting

In this second part to a five-part series, you will learn about the WCF service and hosting. It is excerpted from chapter one of Programming WCF Services, written by Juval Lowy (O'Reilly, 2007; ISBN: 0596526997). Copyright © 2007 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 2
September 27, 2007
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

Hosting 

The WCF service class cannot exist in a void. Every WCF service must be hosted in a Windows process called the host process. A single host process can host multiple services, and the same service type can be hosted in multiple host processes. WCF makes no demand on whether or not the host process is also the client process. Obviously, having a separate process advocates fault and security isolation. It is also immaterial who provides the process or what kind of a process is involved. The host can be provided by IIS, by the Widows Activation Service (WAS) on Windows Vista, or by the developer as part of the application.

A special case of hosting is in-process hosting, or in-procfor short, where the service resides in the same process as the client. The host for the in-proc case is, by definition, provided by the developer.

IIS Hosting

The main advantage of hosting a service in the Microsoft Internet Information Server (IIS) web server is that the host process is launched automatically upon the first client request, and you rely on IIS to manage the life cycle of the host process. The main disadvantage of IIS hosting is that you can only use HTTP. With IIS5, you are further restricted to having all services use the same port number.

Hosting in IIS is very similar to hosting a classic ASMX web service. You need to create a virtual directory under IIS and supply a .svc file. The .svc file functions similar to an .asmxfile, and is used to identify the service code behind the file and class. Example 1-2 shows the syntax for the .svc file.

Example 1-2. A .svc file

<%@ ServiceHost
       Language   = "C#"
       Debug      = "true"
       CodeBehind = "~/App_Code/MyService.cs"
       Service    = "MyService"
%>

You can even inject the service code inline in the .svc file, but that is not advisable, as is the case with ASMX web services.

When you use IIS hosting, the base address used for the service always has to be the same as the address of the .svcfile.

Using Visual Studio 2005

You can use Visual Studio 2005 to generate a boilerplate IIS-hosted service. From the File menu, select New Website and then select WCF Service from the New Web Site dialog box. This causes Visual Studio 2005 to create a new web site, service code, and matching  .svcfile. You can also use the Add New Item dialog to add another service later on. 

The Web.Config file

The web site config file (Web.Config) must list the types you want to expose as services. You need to use fully qualified type names, including the assembly name, if the service type comes from an unreferenced assembly:

  <system.serviceModel>
     <services>
        <service name = "MyNamespace.MyService">
           ...
        </service>
     </services>
  </system.serviceModel>

Self-Hosting

Self-hosting is the name for the technique used when the developer is responsible for providing and managing the life cycle of the host process. Self-hosting is used both in the case of wanting a process (or machine) boundary between the client and the service, and when using the service in-proc—that is, in the same process as the client. The process you need to provide can be any Windows process, such as a Windows Forms application, a Console application, or a Windows NT Service. Note that the process must be running before the client calls the service, which typically means you have to pre-launch it. This is not an issue for NT Services or in-proc. Providing a host can be done with only a few lines of code, and it does offer a few advantage over IIS hosting.

Similar to IIS hosting, the hosting application config file (App.Config) must list the types of the services you wish to host and expose to the world:

  <system.serviceModel>
     <services>
        <service name = "MyNamespace.MyService">
           ...
        </service>
     </services>
  </system.serviceModel>

In addition, the host process must explicitly register the service types at runtime and open the host for client calls, which is why the host process must be running before the client calls arrive. Creating the host is typically done in theMain()method using the classServiceHost, defined in Example 1-3.

Example 1-3. The ServiceHost class

public interface ICommunicationObject
{
  
void Open();
   void Close();
  
//More members
}
public abstract class CommunicationObject : ICommunicationObject
{...}
public abstract class ServiceHostBase : CommunicationObject,IDisposable,...
{...}
public class ServiceHost : ServiceHostBase,...
{
  
public ServiceHost(Type serviceType,params Uri[] baseAddresses);
  
//More members
}

You need to provide the constructor ofServiceHostwith the service type, and optionally with default base addresses. The set of base addresses can be an empty set. Even if you provide base addresses, the service can be configured to use different base addresses. Having a set of base addresses enables the service to accept calls on multiple addresses and protocols, and to use only a relative URI. Note that eachServiceHost instance is associated with a particular service type, and if the host process needs to host multiple types of services, you will need a matching number ofServiceHostinstances. By calling theOpen() method on the host, you allow calls in, and by calling theClose()method, you gracefully exit the host instance, allowing calls in progress to complete, and yet refusing future client calls even if the host process is still running. Closing is typically done on host process shutdown. For example, to host this service in a Windows Forms application:

  [ServiceContract]
  interface IMyContract
  {...}
  class MyService : IMyContract
  {...}

you would have the following hosting code:

  public static void Main()
  {
    
Uri baseAddress = new Uri(http://localhost:8000/);
     ServiceHost host = new ServiceHost(typeof(MyService),baseAddress);

     host.Open();

     //Can do blocking calls:
    
Application.Run(new MyForm());

     host.Close();
  }
 

Opening a host loads the WCF runtime and launches worker threads to monitor incoming requests. Since worker threads are involved, you can perform blocking operations after opening the host. Having explicit control over opening and closing the host provides for a nice feature not easily accomplished with IIS hosting: you can build a custom application control applet where the administrator explicitly opens and closes the host at will, without ever shutting down the host.

Using Visual Studio 2005

Visual Studio 2005 allows you to add a WCF service to any application project by selecting WCF Service from the Add New Item dialog box. The service added this way is, of course, in-proc toward the host process, but can be accessed by out-of-proc clients as well.

Self-hosting and base addresses

You can launch a service host without providing any base address by omitting the base addresses altogether:

  public static void Main()
  {
     ServiceHost host = new ServiceHost(typeof(MyService));

     host.Open();

     Application.Run(new MyForm());

     host.Close();
  }

Do not provide a null instead of an empty list, because that will throw an exception:

  ServiceHost host;
 
host = new ServiceHost(typeof(MyService),null);

You can also register multiple base addresses separated by a comma, as long as the addresses do not use the same transport schema, as in the following snippet (note the use of theparams qualifier in Example 1-3):

  Uri tcpBaseAddress  = new Uri("net.tcp://localhost:8001/");
  Uri httpBaseAddress = new Uri("http://localhost:8002/");

  ServiceHost host = new ServiceHost(typeof(MyService),  
        tcpBaseAddress,httpBaseAddress
);

WCF lets you also list the base addresses in the host config file:

  <system.serviceModel>
    
<services>
       
<service name = "MyNamespace.MyService">
          
<host>
             
<baseAddresses>
                
<add baseAddress = "net.tcp://localhost:8001/"/>
                
<add baseAddress = "http://localhost:8002/"/>
             
</baseAddresses>
           
</host>
          
...
       
</service>
     </services>
  </system.serviceModel>

When you create the host, it will use whichever base address it finds in the config file, plus any base address you provide programmatically. Take extra care to ensure the configured base addresses and the programmatic ones do not overlap in the schema.

You can even register multiple hosts for the same type as long as the hosts use different base addresses:

  Uri baseAddress1  = new Uri("net.tcp://localhost:8001/");
  ServiceHost host1 = new ServiceHost(typeof(MyService),baseAddress1);
  host1.Open();

  Uri baseAddress2  = new Uri("net.tcp://localhost:8002/");
  ServiceHost host2 = new ServiceHost(typeof(MyService),baseAddress2);
  host2.Open();

However, with the exception of some threading issues discussed in Chapter 8, opening multiple hosts this way offers no real advantage. In addition, opening multiple hosts for the same type does not work with base addresses supplied in the config file and requires use of theServiceHostconstructor.

Advanced hosting features

The ICommunicationObject interface supported by ServiceHostoffers some advanced features, listed in Example 1-4.

Example 1-4. The ICommunicationObject interface

public interface ICommunicationObject
{
  
void Open();
  
void Close();
  
void Abort();

   event EventHandler Closed;
  
event EventHandler Closing;
  
event EventHandler Faulted;
  
event EventHandler Opened;
  
event EventHandler Opening;

   IAsyncResult BeginClose(AsyncCallback callback,object state);
   IAsyncResult BeginOpen(AsyncCallback callback,object state);
   void EndClose(IAsyncResult result);
   void EndOpen(IAsyncResult result);

   CommunicationState State
  
{get;}
 
//More members
}
public enum CommunicationState
{
  
Created,
  
Opening,
  
Opened,
  
Closing,
  
Closed,
  
Faulted
}

If opening or closing the host is a lengthy operation, you can do so asynchronously with theBeginOpen()andBeginClose()methods. You can subscribe to hosting events such as state changes or faults, and you can use theStateproperty to query for the host status. Finally, theServiceHostclass also implements theAbort()method.Abort()is an ungraceful exit—when called, it immediately aborts all service calls in progress and shuts down the host. Active clients will get an exception.

The ServiceHost<T> class

You can improve on the WCF-provided ServiceHost class by defining the ServiceHost<T>class, as shown in Example 1-5.

Example 1-5. The ServiceHost<T> class

public class ServiceHost<T> : ServiceHost
{
  
public ServiceHost() : base(typeof(T))
  
{}
  
public ServiceHost(params string[] baseAddresses) :
                               
base(typeof(T),Convert(baseAddresses))
   {}
   public ServiceHost(params Uri[] baseAddresses) : 
               
base(typeof(T),baseAddresses)
   {}
  
static Uri[] Convert(string[] baseAddresses)
  
{
     
Converter<string,Uri> convert = delegate(string address)
                   {
                      return new Uri(address);
                   };
      return Array.ConvertAll(baseAddresses,convert);
   }
}

ServiceHost<T>provides simple constructors that do not require the service type as a construction parameter, and can operate on raw strings instead of the cumbersomeUri. I’ll add quite a few extensions, features, and capabilities toServiceHost<T>in the rest of the book.

WAS Hosting

The Windows Activation Service (WAS) is a system service available with Windows Vista. WAS is part of IIS7, but can be installed and configured separately. To use the WAS for hosting your WCF service, you need to supply a .svcfile, just as with IIS. The main difference between IIS and WAS is that the WAS is not limited to HTTP and can be used with any of the available WCF transports, ports, and queues.

WAS offers many advantages over self-hosting, including application pooling, recycling, idle time management, identity management, and isolation, and is the host process of choice when available; that is, when you can target either a Vista Server machine for scalability or a Vista client machine used as a server machine for a handful of clients only.

Still, the self-hosted process offers singular advantages such as in-proc hosting, dealing with unknown customer environments, and easy programmatic access to the advanced hosting features described previously.

Bindings

 

There are multiple aspects of communication with any given service, and there are many possible communication patterns: messages can be synchronous request/reply or asynchronous fire-and-forget; messages can be bidirectional; messages can be delivered immediately or queued; and the queues can be durable or volatile. There are many possible transport protocols for the messages, such as HTTP (or HTTPS), TCP, P2P (peer network), IPC (named pipes), or MSMQ. There are a few possible message encoding options: you can chose plain text to enable interoperability, binary encoding to optimize performance, or MTOM (Message Transport Optimization Mechanism) for large payloads. There are a few options for securing messages: you can choose not to secure them at all, to provide transport-level security only, to provide message-level privacy and security, and of course there are numerous ways for authenticating and authorizing the clients. Message delivery might be unreliable or reliable end-to-end across intermediaries and dropped connections, and the messages might be processed in the order they were sent or in the order they were received. Your service might need to interoperate with other services or clients that are only aware of the basic web service protocol, or they may be capable of using the score of WS-* modern protocols such as WS-Security and WS-Atomic Transactions. Your service may need to interoperate with legacy clients over raw MSMQ messages, or you may want to restrict your service to interoperate only with another WCF service or client.

If you start counting all the possible communication and interaction options, the number of permutations is probably in the tens of thousands. Some of those choices may be mutually exclusive, and some may mandate other choices. Clearly, both the client and the service must be aligned on all these options in order to communicate properly. Managing this level of complexity adds no business value to most applications, and yet the productivity and quality implications of making the wrong decisions are severe.

To simplify these choices and make them more manageable, WCF groups together a set of such communication aspects in bindings. A bindingis merely a consistent, canned set of choices regarding the transport protocol, message encoding, communication pattern, reliability, security, transaction propagation, and interoperability. Ideally, you would extract all these “plumbing” aspects out of your service code and allow the service to focus solely on the implementation of the business logic. Binding enables you to use the same service logic over drastically different plumbing.

You can use the WCF-provided bindings as is, you can tweak their properties, or you can write your own custom bindings from scratch. The service publishes its choice of binding in its metadata, enabling clients to query for the type and specific properties of the binding because the client must use the exact same binding values as the service. A single service can support multiple bindings on separate addresses.

The Standard Bindings

WCF defines nine standard bindings:

Basic binding

Offered by theBasicHttpBindingclass, this is designed to expose a WCF service as a legacy ASMX web service, so that old clients can work with new services. When used by the client, this binding enables new WCF clients to work with old ASMX services.

TCP binding

Offered by theNetTcpBindingclass, this uses TCP for cross-machine communication on the intranet. It supports a variety of features, including reliability, transactions, and security, and is optimized for WCF-to-WCF communication. As a result, it requires both the client and the service to use WCF.

Peer network binding

Offered by theNetPeerTcpBinding class, this uses peer networking as a transport. The peer network-enabled client and services all subscribe to the same grid and broadcast messages to it. Peer networking is beyond the scope of this book since it requires an understanding of grid topology and mesh computing strategies.

IPC binding

Offered by theNetNamedPipeBindingclass, this uses named pipes as a transport for same-machine communication. It is the most secure binding since it cannot accept calls from outside the machine and it supports a variety of features similar to the TCP binding.

Web Service (WS) binding

Offered by theWSHttpBindingclass, this uses HTTP or HTTPS for transport, and is designed to offer a variety of features such as reliability, transactions, and security over the Internet.

Federated WS binding

Offered by theWSFederationHttpBindingclass, this is a specialization of the WS binding, offering support for federated security. Federated security is beyond the scope of this book.

Duplex WS binding

Offered by theWSDualHttpBindingclass, this is similar to the WS binding except it also supports bidirectional communication from the service to the client as discussed in Chapter 5.

MSMQ binding

Offered by theNetMsmqBindingclass, this uses MSMQ for transport and is designed to offer support for disconnected queued calls. Using this binding is the subject of Chapter 9.

MSMQ integration binding

Offered by theMsmqIntegrationBindingclass, this converts WCF messages to and from MSMQ messages, and is designed to interoperate with legacy MSMQ clients. Using this binding is beyond the scope of this book.

Format and Encoding

Each of the standard bindings uses different transport and encoding, as listed in Table 1-1.

Table 1-1. Transport and encoding for standard bindings
(default encoding is in bold)

Name Transport Encoding Interoperable
BasicHttpBinding HTTP/HTTPS Text, MTOM Yes
NetTcpBinding TCP Binary No
NetPeerTcpBinding P2P Binary No
NetNamedPipeBinding IPC Binary No
WSHttpBinding HTTP/HTTPS Text, MTOM Yes
WSFederationHttpBinding HTTP/HTTPS Text, MTOM Yes
WSDualHttpBinding HTTP Text, MTOM Yes
NetMsmqBinding MSMQ Binary No
MsmqIntegrationBinding MSMQ Binary Yes

Having a text-based encoding enables a WCF service (or client) to communicate over HTTP with any other service (or client) regardless of its technology. Binary encoding over TCP or IPC yields the best performance but at the expense of interoperability, by mandating WCF-to-WCF communication.

Please check back next week for the continuation of this article.

blog comments powered by Disqus
WINDOWS SCRIPTING ARTICLES

- More Windows Scripting Workarounds from Nilpo
- Overloading Methods and More in VBScript
- Improving MFC for Windows Vista
- Regular Expressions in VBScript
- Working with Dates in WMI
- Completing Calendars with VBScript Date Func...
- Building Calendars with VBScript Date Functi...
- Working With Dates and Times in VBScript
- Designing WCF DataContract Classes Using the...
- Understanding Dates and Times in VBScript
- Working With Arrays in VBScript
- Compressed Folders in WSH
- Using .NET Interops in VBScript
- Nilpo`s Scripting Secrets, Vol I
- Database operations using Silverlight 2.0 WC...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 3 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials