如何在WCF中设置多个回退端点

时间:2011-02-11 11:01:57

标签: wcf endpoint fallback

如何设置后备端点。我在conifg文件中指定了多个端点,如下所示。如果无法访问该服务,则我的客户端应检查列表中指定的下一个地址。

客户端配置文件:

<client>
  <endpoint address="http://192.168.1.4/SampleAppWeb/Services/SampleAppService.svc"
        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISampleAppService"
        contract="SampleAppServiceReference.ISampleAppService" name="BasicHttpBinding_ISampleAppService" />
  <endpoint address="http://172.168.12.121/SampleAppWeb/Services/SampleAppService.svc"
        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISampleAppService"
        contract="SampleAppServiceReference.ISampleAppService" name="BasicHttpBinding_ISampleAppService1" />
  <endpoint address="http://127.0.0.1/Services/SampleAppWeb/SampleAppService.svc"
        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISampleAppService"
        contract="SampleAppServiceReference.ISampleAppService" name="BasicHttpBinding_ISampleAppService2" />
  <endpoint address="http://172.168.111.115/Services/SampleAppWeb/SampleAppService.svc"
        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISampleAppService"
        contract="SampleAppServiceReference.ISampleAppService" name="BasicHttpBinding_ISampleAppService3" />          
</client>

代码背后:

var pass = new SampleAppServiceReference.SampleAppServiceClient("BasicHttpBinding_ISampleAppService3");

1 个答案:

答案 0 :(得分:3)

WCF本身没有任何内置功能,但您可以轻松创建一个将为您重试的类。下面的例子显示了一种这样的方式。请注意,如果您的绑定使用会话,您可能需要重新创建客户端(而不是简单地重复使用它),因为如果发生错误,其通道可能会出现故障。

public class StackOverflow_4968244
{
    [ServiceContract]
    public interface ITest
    {
        [OperationContract]
        int Add(int x, int y);
    }
    public class Service : ITest
    {
        public int Add(int x, int y)
        {
            Console.WriteLine("Request at service: {0}", OperationContext.Current.Host.BaseAddresses[0]);
            if (new Random().Next(3) == 0)
            {
                throw new InvalidOperationException("Random error");
            }

            return x + y;
        }
    }
    public class Client : ClientBase<ITest>, ITest
    {
        public Client(string address) : base(new BasicHttpBinding(), new EndpointAddress(address)) { }

        public int Add(int x, int y)
        {
            return this.Channel.Add(x, y);
        }
    }
    public class SafeClient : ITest
    {
        List<Client> clients;
        public SafeClient(params Client[] clients)
        {
            this.clients = new List<Client>(clients);
        }

        public int Add(int x, int y)
        {
            foreach (var client in this.clients)
            {
                try
                {
                    return client.Add(x, y);
                }
                catch (CommunicationException)
                {
                    Console.WriteLine("Error calling client {0}, retrying with next one", client.Endpoint.Address.Uri);
                }
            }

            throw new InvalidOperationException("All services seem to be down");
        }
    }

    public static void Test()
    {
        string baseAddress1 = "http://" + Environment.MachineName + ":8000/Service";
        string baseAddress2 = "http://" + Environment.MachineName + ":8001/Service";
        string baseAddress3 = "http://" + Environment.MachineName + ":8002/Service";
        ServiceHost host1 = new ServiceHost(typeof(Service), new Uri(baseAddress1));
        ServiceHost host2 = new ServiceHost(typeof(Service), new Uri(baseAddress2));
        ServiceHost host3 = new ServiceHost(typeof(Service), new Uri(baseAddress3));
        host1.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
        host2.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
        host3.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
        host1.Open();
        host2.Open();
        host3.Open();
        Console.WriteLine("Hosts opened");

        SafeClient safeClient = new SafeClient(
            new Client(baseAddress1),
            new Client(baseAddress2),
            new Client(baseAddress3));
        for (int i = 0; i < 20; i++)
        {
            Console.WriteLine(safeClient.Add(i, 10));
        }

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host1.Close();
        host2.Close();
        host3.Close();
    }
}