2011-02-11 3 views
2

Comment définir le point de terminaison de secours. J'ai plus d'un point de terminaison spécifié dans le fichier conifg comme suit. Si le service n'était pas accessible, mon client devrait vérifier l'adresse suivante spécifiée dans la liste.Comment définir plusieurs points de terminaison fallback dans WCF

fichier de configuration du client:

<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 Derrière:

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

Alors, quelle est votre question? –

+0

J'accède au noeud final en appelant le nom de configuration du noeud final comme "BasicHttpBinding_ISampleAppService3". Mais, il est possible que mon service ne soit pas disponible à ce point de terminaison. Mais, sûrement l'un des 4 points de terminaison. Donc, je veux configurer le service de telle sorte que, si le service à l'extrémité n'est pas trouvé ou accessible. Il devrait essayer l'un des points de terminaison alternatifs. C'est possible? –

+0

Dans le si j'ai deux enpoints. Un échoue, puis dans le bloc try catch, je pourrais définir le nom d'un autre point de terminaison. Mais, je ne le trouve pas bon ou est-ce que ça va? –

Répondre

3

WCF lui-même n'a pas de fonctionnalité intégrée pour cela, mais vous pouvez facilement créer une classe qui fera la réessayer pour vous. L'exemple ci-dessous en montre un exemple. Notez que si votre liaison utilise une session, vous devrez peut-être recréer le client (au lieu de simplement le réutiliser), car son canal sera probablement bloqué en cas d'erreur.

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