Search code examples
wcfintranet

how to find the service address in WCF client


I created a WCF service and client in same machine, the services address is wrote into Client's code, so I can easily find the service and create connection to service.
Then I try to deploy them into Intranet. The first problem is: how could Client find the address of server. In actual environment, customers can install service at any computer in Intranet, is there any way to let client find the server address?


Solution

  • WCF service could expose a specific endpoint as a discovery endpoint to all clients so that client could find where the service lies. You could even use UDP multicast to enable the service to be discovered by the client.

    You could check the official document.

    https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/wcf-discovery

    I have made a demo, wish it is useful to you.

    Server.

    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost sh=new ServiceHost(typeof(MyService)))
            {
                sh.Open();
                Console.WriteLine("serivce is ready...");
    
                Console.ReadLine();
                sh.Close();
            }
        }
    }
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        string SayHello();
    }
    public class MyService : IService
    {
        public string SayHello()
        {
            return "Hello, I am a Clown";
        }
    

    }

    Server app.config

    <system.serviceModel>
    <services>
      <service name="DiscoveryEndpoint20181024.MyService" behaviorConfiguration="mybehavior">
        <endpoint address="http://10.157.18.188:4800" binding="wsHttpBinding" contract="DiscoveryEndpoint20181024.IService"></endpoint>
        <endpoint kind="discoveryEndpoint" address="http://localhost:9999" binding="wsHttpBinding"></endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="mybehavior">
          <serviceMetadata />
          <serviceDiscovery />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    

    Client.

    class Program
    {
        static void Main(string[] args)
        {
            DiscoveryClient client = new DiscoveryClient("my_client");
            client.ClientCredentials.Windows.ClientCredential.UserName = "administrator";
            client.ClientCredentials.Windows.ClientCredential.Password = "abcd1234!";
            FindCriteria crit = new FindCriteria(typeof(IService));
            FindResponse resp = client.Find(crit);
    
            if (resp != null && resp.Endpoints.Count > 0)
            {
                EndpointDiscoveryMetadata epaddrMtd = resp.Endpoints[0];
                ChannelFactory<IService> factory = new ChannelFactory<IService>(new WSHttpBinding(), epaddrMtd.Address);
                factory.Credentials.Windows.ClientCredential.UserName = "administrator";
                factory.Credentials.Windows.ClientCredential.Password = "abcd1234!";
                IService service = factory.CreateChannel();
                var result=service.SayHello();
                Console.WriteLine(result);
                Console.ReadLine();
            }
    
        }
    }
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        string SayHello();
    }
    
    class DemoService : IService
    {
        public string SayHello()
        {
            OperationContext context = OperationContext.Current;
            return $"the address:{OperationContext.Current.Channel.LocalAddress.Uri}";
        }
    

    }

    Client.config

    <system.serviceModel>
        <client>
          <endpoint name="my_client" kind="discoveryEndpoint" address="http://10.157.18.188:9999" binding="wsHttpBinding"></endpoint>
        </client>
      </system.serviceModel>