Inorder to call the WindowsCommunicationFoundation service, a port or pipe which assigned to the service must be available and the client must know the address endpoints before calling the services.
If the service could use any available address then client can discover that address at runtime. There is a industry standard-based solution which helps in discovering the service addresses.
Address Discovery
Discovery relies on the User Datagram Protocol(UDP). Client uses UDP to broadcast discovery requests for any end-point which supports the contract type. These requests are received by dedicated end-points. The end-points responds back to the client with service-address that support specified contract.
WCF offers a standard discovery endpoint with the type UdpDiscoveryEndpoint
public class DiscoveryEndpoint : ServiceEndpoint {.......} public class UdpDiscoveryEndpoint : DiscoveryEndpoint {.......}
Adding ServiceDiscoveryBehavior the service
ServiceHost host = new ServiceHost(....); host.AddServiceEndpoint(new UdpDiscoveryEndpoint()); host.Description.Behaviors.Add(discovery); host.open();
Adding ServiceDiscoveryBehavior to service using config file
<services> <service name="MyService"> <endpoint kind= "udpDiscoveryEndpoint" /> ....... </service> </services> <behaviors> <serviceBehaviors> <behavior> <serviceDiscovery/> </behavior> </serviceBehaviors> </behaviors>
If you want dynamic base address for your service, the above code is still not perfect as it is requires to add discovery in config file or through code.
Auto Enabling the Discovery through code
public static class DiscoveryHelper { public static Uri AvailableIpcBaseAddress {get; } public static Uri AvailableTcpBaseAddress {get; } }
Uri baseAddress = DiscoveryHelper.AvailableTcpBaseAddress; ServiceHost host = new ServiceHost(typepf(MyService),baseAddress); host.EnableDiscovery(); host.Open();
If the host has not already defined the endpoints for the service, EnableDiscovery will add the default endpoints.
Client-Side Code for Discovering end-points
The client uses the DiscoveryClient class to discover all endpoint addresses of all services that support specified contract:
public sealed class DiscoveryClient : ICommunicationObject { public DiscoveryClient(); public DiscoveryClient(string endpointName); public DiscoveryClient(DiscoveryEndpoint discoveryEndpoint); public FindResponse Find(FindCriteria criteria); }
Discovering and Invoking an Endpoint
DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint() ); FindCriteria criteria = new FindCriteria(typepf(IMyContract)); FindResponse discovered = discoveryClient.Find(criteria); discoveryClient.Close(); //Just grab the first found EndpointAddress address = discovered.Endpoints[0].Address; Binding binding = new NetTcpBinding(); IMycontract proxy = ChannelFactory<IMycontract>.CreateChannel(binding.address); proxy.MyMethod();
Client may discover multiple endpoints supporting the desired contract, it simply invokes the first one in the returned collection.