如何在 WCF 中设置多个后备端点

发布于 2024-10-16 17:16:13 字数 1509 浏览 6 评论 0原文

如何设置回退端点。我在 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");

How to set fall-back endpoint. I'm having more than one endpoint specified in the conifg file like follows. If the service was not accessible, then my client should check the next address specified in the list.

Client Configuration File:

<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>

Code Behind:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

等待我真够勒 2024-10-23 17:16:13

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();
    }
}

WCF itself doesn't have any built-in feature for this, but you can easily create a class which will do the retrying for you. The example below shows one such way. Notice that if your binding uses session, you may need to recreate the client (instead of simply reusing it), as its channel will likely be faulted if an error happens.

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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文