Friday, July 31, 2009

A first look at the Windows Web Services API


The Windows Web Services API is a native implementation of SOAP and can be used to interop transparently with existing WCF services and clients, in addition to offering the ability to completely achieve a client-server implementation in pure native code. I have been longing to play with it ever since I heard Nikola Dudar talk about it at the MVP Summit earlier this year. It’s natively included with Windows 7, but can also be installed and used from older OSes such as XP, Vista, 2003 and 2008. You can write pure native clients using WWS that can connect to an existing managed WCF service, and also write a WWS native service that can be consumed by a WCF client. It’s so compatible that you can replace either a WCF client or a WCF service with a WWS equivalent without the other party being aware of it. In this article, I'll talk about a simple WCF service and its WCF client, and then show how to use WWS to write a native client that can consume the WCF service. I'll then show how the WCF service itself can be replaced transparently with an equivalent WWS service, and how both the WCF and WWS clients can connect to this WWS service without any changes in code.

Note : The examples were written on a 64 bit Windows 7 RC machine running VS 2010 beta 1.

The example WCF service

The first thing to do is to create a very simple WCF service. For our example I'll use a string reversing service that exposes a single method that accepts a string and returns the reversed string. Here’s the service interface :

    [ServiceContract]     interface IStringService     {         [OperationContract]         string Reverse(string s);     }      class MyStringService : IStringService     {         public string Reverse(string s)         {             return new string(s.Reverse().ToArray());         }     }

Here’s the code that shows how the service is created and run.

WSHttpBinding binding = new WSHttpBinding(); binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard; binding.Security.Mode = SecurityMode.None;  Uri baseAddress = new Uri("http://localhost:8000/StringService");  using (ServiceHost serviceHost =    new ServiceHost(typeof(MyStringService), baseAddress)) {     // Check to see if it already has a ServiceMetadataBehavior     ServiceMetadataBehavior smb =        serviceHost.Description.Behaviors.Find();     if (smb == null)         smb = new ServiceMetadataBehavior();      smb.HttpGetEnabled = true;     smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy12;     serviceHost.Description.Behaviors.Add(smb);      // Add MEX endpoint     serviceHost.AddServiceEndpoint(       ServiceMetadataBehavior.MexContractName,       MetadataExchangeBindings.CreateMexHttpBinding(),       "mex"     );      serviceHost.AddServiceEndpoint(       typeof(IStringService), binding, baseAddress);     serviceHost.Open();      Console.WriteLine("The service is running. Press any key to stop.");     Console.ReadKey(); 

I wanted to avoid creating a config file and so everything's done in code, including adding the MEX endpoint. There's not much to explain there, I've used a standard WSHttpBinding and have disabled security (to keep the example simple).

Note : WWS supports several security modes compatible with WCF - so this is not an issue, but the default WCF security mode (Message) is not supported! So make sure that you don't trip on that one.

Simple WCF client in C#

Here's a simple C# console client that uses WCF to connect to the above WCF service and invoke the Reverse method.

See full detail:

No comments: