Processing Service Bus Subscriptions Through WCF - Part 1

Microsoft provides a .NET API for working with Windows Service Bus, therefore you can write applications that interact asynchronously with queues, topics & subscriptions, however MS also provides WCF bindings that natively process service bus messages through WCF. After setting up the configuration, messages can be sent to a WCF service for processing. Let me show you how in this post by building a service that will take engagement requests for planned events. Note: This post assumes that you already have Windows Service Bus running locally and that you are aware of how to build Topics and Subscriptions. Another post will come later that illustrates how to send messages to service bus. For more information on installing service bus, visit here

1. Create a new WCF Service Application.

 2. Renamed the default service and interface files to:

EngagementService.svc
IEngagementService.cs

3. Change the IEngagementService.cs code as follows building the interface that the service will use. It also has the data contract that will pass data about the engagement:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.ServiceModel.Web;

using System.Text;

namespace SB.WCF.Subscription

{

[
ServiceContract]

public interface IEngagementService

{

[
OperationContract(IsOneWay = true, Action = "RequestEngagement")]

[ReceiveContextEnabled(ManualControl = true)]

void RequestEngagement(EngagementRequest request);

}

[
DataContract]

public class EngagementRequest

{

[
DataMember]

public Guid EngagementId { get; set; }[

DataMember]

public EngagementInfo Venue { get; set; }[

DataMember]

public string Description { get; set; }[

DataMember]public List<EngagementEvent> EventSchedule { get; set; }

}

public class EngagementEvent

{

[
DataMember]

public string EventName { get; set; }[

DataMember]public DateTime EventDate { get; set; }

}

public class EngagementInfo

{

[
DataMember]

public int Capacity { get; set; }[

DataMember]public string Location { get; set; }

}

}

4. Before changing the code for the service, there are some references that need to be added. Add the nuget package for Service Bus 1.1 .

5. Add the following code to the EngagementService.svc. I am using a complex object for requesting an engagement to illustrate a little more complexity. The only objective for the code below is to show that the engagement request has been sent to the WCF service:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.ServiceModel.Web;

using System.Text;

using System.ServiceModel.Channels;

namespace SB.WCF.Subscription

{

public class EngagementService : IEngagementService

{

public void RequestEngagement(EngagementRequest request)

{

try

{

Guid engagmentId = request.EngagementId;

var capacity = request.Venue.Capacity;

var location = request.Venue.Location;foreach (var engEvent in request.EventSchedule)

{

var docName = engEvent.EventDate;

var docValue = engEvent.EventName;

}

var desc = request.Description;

var messageProperties = OperationContext.Current.IncomingMessageProperties;

ReceiveContext receiveContext;if (ReceiveContext.TryGet(messageProperties, out receiveContext))

{

receiveContext.Complete(
TimeSpan.FromSeconds(10.0d));

}

}

catch (Exception)

{

//something un-amazing has happened

}

}

}

}

6. Next step is to add the glue, which is the configuration. If you noticed, once Service Bus 1.1 gets installed, it loads a ton of config settings within the web.config. Go ahead and delete what is in the web.config and add the following:

<?xml version="1.0" encoding="utf-8"?>

<configuration><

system.web>

<compilation debug="true" targetFramework="4.5" /><

httpRuntime targetFramework="4.5" />

</system.web><

system.serviceModel>

<behaviors><

serviceBehaviors>

<behavior><!--

To avoid disclosing metadata information, set the values below to false before deployment -->

<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /><!--

To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->

<serviceDebug includeExceptionDetailInFaults="false" /></

behavior>

</serviceBehaviors><

endpointBehaviors>

<behavior name="EndpointBehavior"><

transportClientEndpointBehavior>

<tokenProvider><

windowsAuthentication>

<stsUris><

stsUri value=https://ServerName:9355/ServiceBusDefaultNamespace />

</stsUris></

windowsAuthentication>

</tokenProvider></

transportClientEndpointBehavior>

</behavior></

endpointBehaviors>

</behaviors><

services> <service name="SB.WCF.Subscription.EngagementService">

<endpoint name="EngagementProcessor"

listenUri="sb://ServerName/ServiceBusDefaultNamespace/EngagementTopic/subscriptions/EngagementSub1"

address="sb://ServerName/ServiceBusDefaultNamespace/EngagementTopic"

binding="netMessagingBinding"

bindingConfiguration="messageBinding"

contract="SB.WCF.Subscription.IEngagementService"

behaviorConfiguration="EndpointBehavior"/>

</service></

services>

<bindings><

netMessagingBinding>

<binding name="messageBinding" closeTimeout="00:03:00" openTimeout="00:03:00" receiveTimeout="00:03:00" sendTimeout="00:03:00" sessionIdleTimeout="00:01:00" prefetchCount="1"><

transportSettings batchFlushInterval="00:00:01"></transportSettings>

</binding></

netMessagingBinding>

</bindings><!--

<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />-->

<extensions><!--

In this extension section we are introducing all known service bus extensions. User can remove the ones they don't need. -->

<behaviorExtensions><

add name="transportClientEndpointBehavior" type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

</behaviorExtensions><

bindingElementExtensions>

<add name="netMessagingTransport" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingTransportExtensionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /></

bindingElementExtensions>

<bindingExtensions><

add name="netMessagingBinding" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

</bindingExtensions></

extensions>

</system.serviceModel><

system.webServer> <modules runAllManagedModulesForAllRequests="true" />

<!--

To browse web app root directory during debugging, set the value below to true.

Set to false before deployment to avoid disclosing web app folder information.

-->

<directoryBrowse enabled="true" /></

system.webServer>

</configuration>

I want to explain two settings from the web.config are the following:

listenUri="sb://ServerName/ServiceBusDefaultNamespace/EngagementTopic/subscriptions/EngagementSub1"

address="sb://ServerName/ServiceBusDefaultNamespace/EngagementTopic"

ListenUri listens to the subscription where address points to the topic where messages are being sent.

There are some ok examples out there but nothing fully complete in my opinion. Must of the samples use Azure Service Bus which is fine, but I wanted to show strictly how to use Windows Service Bus, as a pure on-premise setup. My next post will demonstrate how to send messages to the service created in this post. Fire away if you have any questions.

Currently rated 5.0 by 3 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: BayerWhite
Posted on: 4/18/2014 at 2:39 AM
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Comments

Comments are closed