WCF with Service Bus
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" />
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>
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)
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 |
Dictates how the service (subscriber) part of the system will negotiate the connection with the MS Service Bus Relay service. Default is AutoDetect.
ConnectivityMode |
Behavior |
Tcp |
Connect on port 828 (SSL) |
Http |
Connect over HTTP |
AutoDetect |
Use TCP if possible, fallback on HTTP otherwise. |
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.
· 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.
· 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 ??
· 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"); }
· HTTP/REST based
· SOAP (no WS-* support)
· SOAP (WS-* support, excluding transaction flow)
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.