2013-07-09 20 views
6

Mam zdalny serwis WWW WCF, z którym łączę się z mojej aplikacji.Upewnij się, że wychodzące żądania WCF są wykonywane przy użyciu określonego interfejsu sieciowego.

Wniosek może być uruchomiony na serwerze z wieloma adresami IP (lub wieloma interfejsami sieciowymi fizycznych)

muszę się upewnić, że mogę kontrolować, które adres IP jest używany do żądania wychodzącego, a nie tylko używając "preferowanego" interfejsu zgodnie ze zwykłymi regułami metrycznymi.

Powodem tego jest to, że wiele kopii oprogramowania zostanie uruchomionych na tym samym komputerze, z których każdy jest powiązany z określonym adresem IP dla własnych operacji, a podłączona usługa zdalna musi wiedzieć, który z nich jest używany. aby połączyć się z nim później (ponieważ błędny adres oznacza połączenie z niewłaściwą usługą)

Przy starszych usługach ASMX odbywa się to poprzez przesłonięcie GetWebRequest(Uri uri) w klasie cząstkowej wygenerowanej dla usługi. Ale nie mogę w ogóle dowiedzieć się, jak to zrobić z WCF.

Na unrelated SO post, MVP @JohnSaunders zasugerował, że może to być możliwe poprzez przejęcie całego mechanizmu transportu używanego przez WCF. Ale jeszcze nie wiem, jak to zrobić.

+0

Co powiecie na http://stackoverflow.com/questions/3249846/specify-the-outgoing-ip-address-to-use-w-wcf-client –

+0

@BradChristie Pierwsza odpowiedź to poziom operacyjny, druga odpowiedź nie stosuje się do WCF i stosuje się tylko do nieprzetworzonych żądań SOAP, stąd dlaczego to pytanie nie ma zaakceptowanej odpowiedzi. – PhonicUK

+2

BTW, w zależności od adresu IP, aby zdecydować, z którym połączeniem się jest ... rozwiązaniem nieoptymalnym. –

Odpowiedz

3

To skomplikowane problem, którego WCF nie wydaje się szczególnie dobrze spełniać.

Jedynym komponentem w platformie .NET, który wydaje się bezpośrednio zajmować się problemem adresu klienta , jest klasa ServicePoint. W szczególności ma właściwość BindIPEndPointDelegate, która pozwala kontrolować sposób wybierania adresu IP klienta. Dokumentacja dla właściwości obejmuje to:

techniki wyważania

Niektóre wymagają obciążenia klienta do korzystania z konkretnego lokalny adres IP i numer portu, zamiast IPAddress.Any (lub IPAddress.IPv6Any Internet Protocol Version 6) i efemeryczny portu. Twój BindIPEndPointDelegate może spełnić to wymaganie.

Zatem powinieneś być w stanie zmodyfikować punkt usług powiązanych z adresu URL w kodzie tak:

var servicePoint = ServicePointManager.FindServicePoint(
    new Uri("http://contoso.com/service.svc")); 

servicePoint.BindIPEndPointDelegate = 
    (sp, remote, retryCount) => new IPEndPoint(address, portNumber); 

Oczywiście ten rodzaj kodu wymaga twoje zajęcia mieć świadomość protokołu i adresu punktu końcowego klient będzie komunikował się z.Najprawdopodobniej najlepiej będzie ustawić tę logikę jako zachowanie klienta, które można zastosować do kanału klienta.

+1

Zakładam, że korzystasz z HTTP, ponieważ wspomniałeś o usługach ASMX. To rozwiązanie działa tylko w przypadku protokołu HTTP, ponieważ ServicePointManager obsługuje tylko ten stos. –

0

można użyć właściwości komunikatu (HttpRequestMessageProperty), aby dodać nagłówki HTTP do dowolnych wychodzących żądań. Musisz utworzyć "zakres", w którym właściwość zostanie dodana do bieżącego "kontekstu operacji" i dołączyć właściwość, z wszystkimi wybranymi nagłówkami, do właściwości komunikatu wychodzącego kontekstu.

proszę spojrzeć na to:

how-to-override-getwebrequest-method-using-service-reference-instead-of-web-reference-in-wcf

0

użyj: Nowa klasa:

using System.Web.Services.Protocols; 
using System.Windows.Forms; 
using System; 

public static class ExtensionMethods 
{ 
    public static string ApplyServerURL(this SoapHttpClientProtocol service) 
    { 
     try 
     { 
      string name = service.GetType().Name; 
      return string.Format("{0}{1}.svc", Settings.Instance.ServerAddress, name); 
     } 
     catch 
     { return string.Empty; } 
    } 
} 

A teraz jest coś takiego:

YourService us = new YourService(); 
us.Url = us.ApplyServerURL();