WCF Feb CTP: Multiple ServiceEndpoints sharing a common Uri to listen for messages.

With the feb CTP release we added the ability for multiple ServiceEndpoint's on a service to share a common listen URI. I wanted to walk through a sample explaining how to achieve this.

Lets assume we have this sample Service.

[ServiceContract]

public interface IService

{

[OperationContract]

String SayHello(String s);

}

Now we create a ServiceHost which will expose two endpoints.

Binding binding = new NetTcpBinding();

Uri commonListenUri = "net.tcp://localhost:9999/CommonListen";

ServiceHost sh = new ServiceHost(typeof(MyIServiceImplementation), new Uri("net.tcp://localhost:8888/Sample));

sh.AddServiceEndpoint(typeof(IService), binding, "/Endpoint1", commonListenUri);

sh.AddServiceEndpoint(typeof(IService), binding, "/Endpoint2", commonListenUri); <== Note we are reusing the same binding object

So to enable sharing of listen uri, two endpoints needs to share the binding object and pass in the listen uri as an argument to AddServiceEndpoint call. Its that simple. Now lets see how a client can connect to endpoint "/Endpoint1" and execute an operation.

using (ChannelFactory<IService> factory= new ChannelFactory<IService>(new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:8888/Endpoint1")))

{

          factory.Endpoint.Behaviors.Add( new ViaUriBehavior("net.tcp/localhost:9999/CommonListen"));

          IService proxy = factory.CreateChannel();

         Console.WriteLine(proxy.SayHello("Hello from client" ));

}

Notice that the way we provide the Via uri is different in the feb CTP. Previously users would pass it as an argument to the ChannelFactory constructor but now its has to be added as a behavior.

Adding a ViaBehavior marks the underlying transport to connect to that Uri but actual EndpointAddress specified in the factory is sent as the "To" header in the message. On the service, we now have one listener listening on the listen uri and decides which endpoint should process the message based on the "To" header.

If you are using svcutil to generate the proxy class then you would add the ViaUriBehavior on [GeneratedProxyObjectInstance].Endpoint.Behaviors.

Note: To share a listen uri, all the endpoints in the group should use the same binding and should specify the same binding object in the AddServiceEndpoint call. So if in the above sample you would get an exception if you were to add the endpoints like whats shown below.

sh.AddServiceEndpoint(typeof(IService), new NetTcpBinding(), "/Endpoint1", commonListenUri);

sh.AddServiceEndpoint(typeof(IService), new NetTcpBinding(), "/Endpoint2", commonListenUri);

Mahesh