One Way Street

One-Way-Calls in WCF are an effective way to perform an action that you don’t care when (or even if) it completes. If you do care about tracking success or logging failure I’ll have a follow up post to cover that. The simplest example is something along the lines of a non-critical system status update; achieved by sending an email, a text message or an even more modern tweet post, informing someone of an system state/event.

One Way

To begin with lets get a one way method call sent off to a service that may (or may not) be currently active. To achieve this I will be making use of Microsoft’s Message Queuing system (MSMQ). At the end of the post I’ll have a brief discussion on MSMQ.

Now, the key attribute to achieve one-way is:

[OperationContract(IsOneWay = true)]

It is applied to methods on the Service Contract interface. A quick thing to note here is for the NetMsmq Binding in WCF the IsOneWay is required as the queue does not support a duplex channel scenario, and if you miss-configure your methods this exception will quickly pop up on load:

Contract Requires Two-Way Exception

Contract Requires Two-Way Exception

To configure your App.Config file we make use of the net.Msmq binding. This config follows the same pattern in previous posts. This endpoint can exist alongside other types of endpoints, but should be separated into it’s own manager that will handle all the OneWay endpoints/methods.

<services>
   <service name="Notification.NotificationImplementation.OneWayNotificationManager">

      <endpoint name="netMsmq_IOneWayNotificationService"
         address="net.Msmq://MACHINE_NAME/oneWayNotificationService"
         binding="netMsmqBinding"
         bindingConfiguration="netMsmq"
         contract="Notification.NotificationServiceContract.IOneWayNotificationService" />

   </service>
</services>

Now for the full interface definition, it’s as just like the previous examples except with the IsOneWay attribute. Another addition I’ve included here is DeliveryRequirements.Required it assist in defining a solid rule that this interface is designed only for MSMQ calls. The other 2 options on the attribute are ‘NotRequired’ and ‘Allowed’.

[ServiceContract(Name = "IOneWayNotificationService", Namespace = "http://your.domain/2009/")]
[DeliveryRequirements(QueuedDeliveryRequirements = QueuedDeliveryRequirementsMode.Required)]
public interface IOneWayNotificationService
{
   [OperationContract(IsOneWay = true)]
   [TransactionFlow(TransactionFlowOption.Allowed)]
   void SendNotification(NotificationRequest request);
}

Creating the host is identical to previous examples:

ServiceHost oneWayNotificationManager = new ServiceHost();

One additional approach to make life just that little bit easier, making use of ServiceModelEx‘s method VerifyQueue() to create the actual queue and verify access to it. As a reminder my ServiceModelEx overview is here.

//With a quick and dirty zero index array element if you only have 1 endpoint.
ServiceModelEx.QueuedServiceHelper.VerifyQueue(oneWayNotificationManager.Description.Endpoints[0]);

//Or iterate over each endpoint in a loop
foreach(ServiceEndpoint endpoint in oneWayNotificationManager.Description.Endpoints)
   ServiceModelEx.QueuedServiceHelper.VerifyQueue(endpoint);

oneWayNotificationManager.AddErrorHandler();
oneWayNotificationManager.Open();

Now calling the method from a client application (or other service) is just like any other call except there will be no response.

using ( OneWayNotificationServiceProxy proxy = new OneWayNotificationServiceProxy() )
{
   NotificationRequest request = new NotificationRequest();
   request.someProperty = true;

   proxy.SendNotification(request);
}

The client sending the call will need to have an net.Msmq endpoint configured in it’s App.Config:

<system.serviceModel>
   <client>
      <endpoint name="netMsmq_IOneWayNotificationService"
         address="net.Msmq://MACHINE_NAME/OneWayNotificationService"
         binding="netMsmqBinding"
         bindingConfiguration="netMsmq"
         contract="Notification.NotificationServiceContract.IOneWayNotificationService" />
      </client>
   </system.serviceModel>

It’s as simple as that, open up the Computer Management Console to view the messages show up in the queue. In the next post I’ll go into some more detail about the queues.

Computer Management Console

Computer Management Console

MSMQ

There’s a lot to say about MSMQ, and a variety of ways to use with WCF. In this example basically it will hold the message until our service is ready to use it, and in this post we’re not concerned if something goes wrong. Two quick things I want to bring up about MSMQ are:

  1. It is not installed by default; you need perform a few steps – MS Technet has the instructions.
  2. To make use of “Public Queues” the system needs to be part of a domain with Active Directory, otherwise all you have access is to “Private Queues”. To directly quote the MSMQ Faq:
    • “MSMQ utilizes Active Directory for security information related to encryption and decryption, or message authentication. MSMQ also uses Active Directory for public queue lookups – in this way the sending or receiving applications do not need to know the machine-name of the computer hosting the destination queue.”

Being a Good Host 2 – Grouping Multiple Services

Previously I gave a simple overview of hosting a single services in a form. If you’re developing a larger system and you have broken down business across several services, for reasons ranging from code management, to partitioning development tasks across teams, to reducing the compile time for a visual studio solution. You’re likely to want to keep the services separate but kick them off in groups; “Core System Services”, “Supporting Services”, “Reporting/Administration Services”, etc.

The most manual part is to merge the endpoints from all your individual config files into 1 single App.Config file that will accompany your production level deployment approach. This can also be used to package up the initial services mid-way through development when they are unlikely to change and it saves hassle running them as a group.

Watch-out-for: the contract definition in the config file; make sure it’s a fully qualified namespace for each service end point. You add individual references to your host application for each service you’re including.

<endpoint  
  address="net.tcp://localhost:8001/Patients"  
  binding="netTcpBinding"  
  bindingConfiguration="myNetTcpBinding"
  contract="Server.Patient.IPatientServiceContract" 
 />

For this example I’ve simply chosen to run it as a standard windows service, where all I need to do is implement OnStart() and OnStop() and if you think you need to OnPause() and OnContinue() or any of the other ServiceBase methods.

public partial class MultiServiceHost : ServiceBase
{
   private IList<ServiceHost> hosts = new List<ServiceHost>();
}

The OnStart() is simply a list of each of your services you’re grouping to run together.

protected override void OnStart(string[] args)
{
   try
   {
      hosts.Add(new ServiceHost(typeof(PatientService)));
      hosts.Add(new ServiceHost(typeof(MedicalProcedureService)));
      hosts.Add(new ServiceHost(typeof(OtherService)));
      //more hosts...
      StartServices();
   }
   //Catch ()...
}

A loop to kick off all the services, that’s called after they’re all added.

private void StartServices()
{
   foreach (ServiceHost h in hosts)
   {   h.Open();   }
}

Closing them all off upon shutdown of the host.

protected override void OnStop()
{
   foreach (ServiceHost host in _hosts)
   {
      if (host != null)
         host.Close();
   }
}

It’s that simple.

Being a Good Host

Hosting a WCF application is quite simple. There are 3 available hosting options IIS (Internet Information Services), WAS (Windows Activation Service) under Vista/Server 2008 and an ordinary (windows form/console) application.

The quickest to getting your project up and running is a windows form (or console) app. This way you can begin development quickly.

//program.cs
static class Program
{
   [STAThread]
   static void Main()
   {
      Application.Run(new FormWcfHost());
   }
}

Then for the windows form:

public partial class FormWcfHost : Form
{
   private ServiceHost<MyService> serviceManager 
      = new ServiceHost<MyService>();

   public FormWcfHost()
   {
      serviceManager.Open();
   }
		
   private void FormWcfHost_FormClosed(object sender, 
       FormClosedEventArgs e)
   {
      serviceManager.Close();
   }
}

It’s that simple.

The production level hosting decissions are just slightly more involved. Basically if you have an installation of Windows 2008 Server available then it’s ideal to make use of WAS to host it. Otherwise the choice can be argued between IIS6 hosting or just running it as a standard windows service on a Windows 2003 depolyment.

The advantages that WAS offers are; application pooling, isolation, identity management. So is the more scalable choice.

The WCF Run-Down

Windows Communication Foundation (WCF) is a framework for building service-oriented applications. Using WCF, you can send data as asynchronous messages from one service endpoint to another.

Great… Lets try it out…

So how do you go about getting something up and running? We have to start somewhere… so let’s start by covering some of the basic concepts.

Service Contract
The bulk of the work in setting up WCF is achieved by the most simplest of attribute placement on an interface (or class). Best practice is to apply it to an interface.

[ServiceContract]
public interface IMyServiceContract
{
    [OperationContract]
    string GetData(int value);
}

Bindings

Define the configuration of the way messages will be communicated, transported and encoded. The examples being Synchronous vs Asynchronous, HTTP vs TCP, compression vs interoperability. This list and set of comparisons is by no means exhaustive. But for the majority of cases of you’re likely to choose either NetTCP or MSMQ (queued) if both systems (client+server) are using WCF. Otherwise you have an ASMX based client and your choice really should be WSHttpBinding (otherwise you’re supporting a legacy system and you have no choice but to use BasicHttpBinding.

Endpoints

The address to which clients can connect to the service. The key things to note are the protocol type in this case net.tcp, the port (anything high up will do), the bindingConfiguration that allows you to further define the communication method, and the reference to the contract defined earlier. The service can and expose multiple endpoints, and they can each be of varying type and configuration.

<system.serviceModel>
  <services>
    <service name="MyService">
      <endpoint
        address="net.tcp://localhost:8001/MyService" 
        binding="netTcpBinding"
        bindingConfiguration="myNetTcpBinding"
        contract = "IMyServiceContract" />
    </service>
    <bindings>
      <netTcpBinding>
        <binding name="myNetTcpBinding" 
          transactionFlow="true" />
        </netTcpBinding>
    </bindings>
  </services>
</system.serviceModel>

Just a tip if you find yourself debugging calls from a client application and if you’re anything like me and like to edit code live while continuing to debug you will cop a lot of timeout exceptions. It’s therefore handy to setup extra bindings you can use them in development naming them something obviously not required for production like ‘DevExtendedTimeouts’ (hopefully so someone remembers to remove them before shipping) the length of the name itself makes them stand out. This way you have a few more minutes before you get hit with a timeout – alter length to your own taste. In a future post I will cover how this can also be achieved programmatically including the use of compiler directives.

<bindings>
   <netTcpBinding>
      <binding name="myNetTcpBinding_DevExtendedTimeouts" 
         transactionFlow="true"
         sendTimeout="00:05:00" />
   </netTcpBinding>
</bindings>

Client Application

Once the service contract has been imported a proxy responsible for managing the life-cycle and connection to the service is what the client application can invoke to make calls. The client end configuration needs to list all the endpoints exposed by the service that it intends to use. A key thing to note is the client calls via the proxy should always perform a close action, to free up resources on the service. This can simply be achieved via a using() statement, your service implementation should also implement IDisposable.

    using ( IMyServiceContract proxy = new MyClient() )
    {
        proxy.SomeMethod();
    }

Client configuration leads onto the topic of hosting the WCF service which will be the next post “Being a Good Host“.