WCF with Service Bus

References:

·         Developer’s Guide

WCF Simplest Example:

Wiring

Service Bus adds set of WCF bindings* that are the Service Bus equivalent for many of the existing bindings. In the simplest cases, moving to Service Bus is simply a case of changing the <endpoint>’s binding and address attributes:

      <service name="WcfService1.HelloServiceBus">
        <endpoint address="sb://davetest2.servicebus.windows.net/helloservicebus" 
                  behaviorConfiguration="sharedSecretClientCredentials" 
                  binding="netTcpRelayBinding" contract="WcfService1.IHelloServiceBus"/>
      </service>
 

* specifically: basicHttpRelayBinding, webHttpRelayBinding, ws2007HttpRelayBinding, netTcpRelayBinding, netOnewayRelayBinding, netEventRelayBinding are added to %windir%\Microsoft.NET\Framework\v4.0.30319\Config\machine.config. If you don’t install the SDK, you may not have theses entries. The RelayConfigurationInstaller.exe tool can be used to add them.

 

The above uses the simplest auth mechanism (other than none): shared secret

      <endpointBehaviors>
        <behavior name="sharedSecretClientCredentials">
          <transportClientEndpointBehavior credentialType="SharedSecret">
            <clientCredentials>
              <sharedSecret issuerName="[ValueFromPortal]" issuerSecret="[ValueFromPortal]"/>
            </clientCredentials>
          </transportClientEndpointBehavior>
        </behavior>
      </endpointBehaviors>

 

Other options are: SimpleWebToken, Saml and Unauthenticated.

To connect to the relay service with no client auth, add a bindingConfiguration to the <endpoint> that points to a binding containing <security relayClientAuthenticationType="None" />

 

Making Service Publically Discoverable

Publically discoverable services are listed in an atom feed at the services root address (e.g. http://davetest2.servicebus.windows.net). By default services are private. Services only appear in the feed while they are open (running).

A service is made discoverable by adding a serviceRegistrySettings behavior to the host:

ServiceHost host = new ServiceHost(typeof(HelloServiceBus));

 

// Create the ServiceRegistrySettings behavior for the endpoint.

ServiceRegistrySettings serviceRegistrySettings = 

         new ServiceRegistrySettings(DiscoveryType.Public);

// serviceRegistrySettings.DisplayName += "HelloThere"; // If set, changes the title element of the feed

 

// Add the Service Bus credentials to all endpoints specified in configuration.

foreach (ServiceEndpoint endpoint in host.Description.Endpoints)

{

    endpoint.Behaviors.Add(serviceRegistrySettings);

}

 

// Open the service.

host.Open();

 

Resulting feed (while code above is running):

<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Publicly Listed Services</title> 
  <subtitle type="text">This is the list of publicly-listed services currently available</subtitle> 
  <id>uuid:ca1a98dc-59cb-4ac6-92b5-573014b16eeb;id=5893</id> 
  <updated>2011-08-02T20:25:55Z</updated> 
  <generator>Microsoft® Windows Azure AppFabric - Service Bus</generator> 
  <entry>
    <id>uuid:ca1a98dc-59cb-4ac6-92b5-573014b16eeb;id=5894</id> 
    <title type="text">helloservicebus</title> 
    <updated>2011-08-02T20:25:55Z</updated> 
    <link rel="alternate" href="sb://davetest2.servicebus.windows.net/helloservicebus/" /> 
  </entry>
</feed>

 

URIs

The sb: protocol is used for TCP based endpoints. The http[s]: protocol is used for HTTP based endpoints.

Listening on a path (e.g. sb://davetest2.servicebus.windows.net/dave/was/here/helloservicebus) is fully supported, and the discovery feed  works as you’d hope (only the immediate children are shown. e.g. http://davetest2.servicebus.windows.net/ only shows an entry for http://davetest2.servicebus.windows.net/dave, and http://davetest2.servicebus.windows.net/dave/was/here is the only address to show the actual service)

Client Ports

HTTP/S just needs 80/443.

TCP requires these outgoing ports (no incoming ports required)

Port

Purpose

9350

One-way TCP

9351

One-way TCP (SSL)

9352, 9353

Bidirectional TCP

 

ServiceBusEnvironment.SystemConnectivity.Mode

Dictates how the service (subscriber) part of the system will negotiate the connection with the MS Service Bus Relay service. Default is AutoDetect.

ConnectivityMode
Enum

Behavior

Tcp

Connect on port 828 (SSL)

Http

Connect over HTTP

AutoDetect

Use TCP if possible, fallback on HTTP otherwise.

 

Note on SSL

A message secured by SSL is encrypted over the wire, but passes through the internals of the MS service unencrypted. If this is a concern, use a message security mode to encrypt everything but address information.

 

New bindings

NetOnewayRelayBinding

·         Service operations must be marked as being one way ([OperationContract(IsOneWay = true)]. Notice the casing of OneWay is different in the OperationContract attribute and the binding name.

·         One way binding cannot return anything, include a fault.

·         One way bindings block just like normal bindings until they are read from the WCF incoming queue and handed off for processing. What this means is that if the server is backed up with requests, the client will block even if it is marked as one-way.

NetEventRelayBinding

·         Derives from NetOnewayRelayBinding

·         Allows multiple servers (subscribers) to listen, all of whom receive a copy of the message.

·         ?? What about return results? I’m guessing these are all one way operations as well ??

NetTcpRelayBinding

·         Most commonly used (probably fair to describe it as the default selection)

·         SOAP 1.2, TCP, binary serialization

·         Supports <binding … connectionMode="seeTableBelow" …>

TcpConnectionMode

Behavior

Relayed (default)

All traffic goes through the MS servers

Hybrid

Traffic starts by going through the MS servers, but in the background an attempt is made to directly connect the publisher & subscriber. If the direct connection succeeds, all traffic is then sent directly.

Channel.GetProperty<IHybridConnectionStatus>().ConnectionStatChanged += (o,e) => { Console.WriteLine("upgraded"); }

WebHttpRelayBinding

·         HTTP/REST based

BasicHttpRelayBinding

·         SOAP (no WS-* support)

WS2007HttpRelayBinding

·         SOAP (WS-* support, excluding transaction flow)

 

ACS Integration

The claims Service Bus is interested in are: listen, send, and manage

ACS endpoint is: yournamespace-sb.accesscontrol.windows.net

The relay service removes the ACS token before forwarding the message.