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.”
Advertisements

One thought on “One Way Street

  1. […] form a queue, for poison. In the previous post about using MSMQ to facilitate One-Way-Calls I covered some of the basics of setting up a MSMQ binding. In that scenario if a consumer of that […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s