如何在 WCF 客户端中查找服务地址

how to find the service address in WCF client

我在同一台机器上创建了一个 WCF 服务和客户端,服务地址写在客户端的代码中,所以我可以很容易地找到服务并创建与服务的连接。
然后我尝试将它们部署到 Intranet 中。第一个问题是:客户端如何找到服务器的地址。实际环境中,客户可以在内网任意一台电脑上安装服务,请问有什么办法可以让客户找到服务器地址吗?

WCF 服务可以将特定端点作为发现端点公开给所有客户端,以便客户端可以找到服务所在的位置。您甚至可以使用 UDP 多播来使服务能够被客户端发现。

你可以查看官方文档

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

我做了一个demo,希望对你有用。

服务器。

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";
    }

}

服务器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>

客户端.

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>