2

フォールバック エンドポイントの設定方法。次のように、構成ファイルで複数のエンドポイントを指定しています。サービスにアクセスできなかった場合、クライアントはリストで指定された次のアドレスを確認する必要があります。

クライアント構成ファイル:

<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");
4

1 に答える 1

3

WCF 自体にはこのための組み込み機能はありませんが、再試行を行うクラスを簡単に作成できます。以下の例は、そのような方法の 1 つを示しています。バインディングがセッションを使用する場合、エラーが発生するとクライアントのチャネルに障害が発生する可能性があるため、クライアントを (単純に再利用するのではなく) 再作成する必要がある場合があることに注意してください。

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();
    }
}
于 2011-06-09T04:59:36.033 に答える