Укажите исходящий IP-адрес для использования с клиентом WCF - PullRequest
2 голосов
/ 14 июля 2010

Как определить LocalEndPoint для использования клиентом WCF при вызове службы WCF (если клиентский компьютер имеет несколько IP-адресов)?

У меня есть машина, расположенная в DMZс двумя IP-адресами внешний IP-адрес может быть достигнут через брандмауэр через VPN-соединение с нашего веб-сервера, расположенного у внешнего поставщика услуг.На этом компьютере запускается пользовательский сервер приложений на основе WCF и Unity, который должен выступать в качестве шлюза уровня прокси или приложения (ALG).Он должен принимать сервисные вызовы от веб-сервера и использовать фабрику клиентов wcf для регенерации сервисных вызовов, переадресовывая их на реальный сервер приложений в локальной сети.

При повторном создании сервисных вызовов на этом прокси-сервере с помощьюНа фабрике клиентов wcf клиент wcf должен использовать второй внутренний IP-адрес этого компьютера, поскольку только сообщения, поступающие с этого внутреннего IP-адреса, будут проходить через межсетевой экран для доступа к серверу приложений в локальной сети.К сожалению, наши прокси-клиенты wcf всегда предпочитают создавать исходящие сообщения, используя первые «внешние» IP-адреса.Я ищу способ явной установки IP-адреса для использования прокси-клиентами wcf.

Я мог найти только один элемент привязки WCF, который позволяет определять LocalEndPoint или ClientBaseAddress: CompositeDuplexBindingElement.Насколько я понимаю из документации, это свойство предназначено для того, чтобы сообщать серверу, куда отправлять ответные сообщения асинхронности, так что это настройка, отличная от того, что я ищу.

Любая идея, что я могу сделать, чтобы прийтик работоспособному решению?

Заранее благодарим за любой полезный совет !!

Похоже, что подобный вопрос, просто используя TcpClient / Sockets вместо WCF: Укажите исходящий IP-адрес для использования с TCPClient / Socket в C #

И еще один, на этот раз относительно SoapClient: Привязка нового SoapClient к определенному IP-адресу перед отправкой исходящего запроса

Ответы [ 3 ]

5 голосов
/ 12 сентября 2012

Мне было сложно найти ответ на этот вопрос самому, поэтому я поделюсь своим решением на тот случай, если кто-нибудь еще придет сюда.

Ниже приведен метод, который возвращает wapf soapservice.Код будет пытаться использовать определенный ip, если он доступен.Я сделал эту проверку, чтобы она работала и на тестовой машине.

    public static proposalSoapClient getService()
    {
        string serviceurl = "http://somesite.dk/proposal.asmx";
        var localIpAddress = IPAddress.Parse("123.123.123.123");
        var hasLocalAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList.Any(ip => ip.AddressFamily == AddressFamily.InterNetwork && ip.Equals(localIpAddress));

        var binding = new System.ServiceModel.BasicHttpBinding("proposalSoap"); //name of binding in web.config
        var endpoint = new EndpointAddress(serviceurl);
        ServicePoint servicePoint = ServicePointManager.FindServicePoint(new Uri(serviceurl));
        servicePoint.BindIPEndPointDelegate = (sp, rm, retryCount) => { return new IPEndPoint(hasLocalAddress ? localIpAddress : IPAddress.Any, 0); };
        return new proposalSoapClient(binding, endpoint);
    }

Также, когда я на тестовом сервере, мне приходилось использовать прокси для доступа к сервису.(Я использовал Fiddler в качестве прокси на машине, которая имела доступ к службе).Ниже приведен тот же код, но с добавленным разделом для прокси на тестовом сервере.

    public static proposalSoapClient getService()
    {
        string serviceurl = "http://somesite.dk/proposal.asmx";
        var localIpAddress = IPAddress.Parse("123.123.123.123");
        var hasLocalAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList.Any(ip => ip.AddressFamily == AddressFamily.InterNetwork && ip.Equals(localIpAddress));

        var binding = new System.ServiceModel.BasicHttpBinding("proposalSoap"); //name of binding in web.config
        var endpoint = new EndpointAddress(serviceurl);
        ServicePoint servicePoint = ServicePointManager.FindServicePoint(new Uri(serviceurl));

    #if DEBUG
        Uri proxyUri = new Uri("http://someothersite.dk:8888");
        binding.ProxyAddress = proxyUri;
        binding.BypassProxyOnLocal = false;
        binding.UseDefaultWebProxy = false;
        servicePoint = ServicePointManager.FindServicePoint(serviceurl, new WebProxy(proxyUri, false));
    #endif

        servicePoint.BindIPEndPointDelegate = (sp, rm, retryCount) => { return new IPEndPoint(hasLocalAddress ? localIpAddress : IPAddress.Any, 0); };
        return new proposalSoapClient(binding, endpoint);
    }
1 голос
/ 01 февраля 2012

Это более старая тема, но у меня есть предложение для любого, кто найдет эту тему, так как это привело меня к поиску немного другого решения. У нас есть два процесса, которые нам нужно было запустить на разных процессах на одном сервере.

Проблема была в том, что каждый по умолчанию выбрал основной адрес, который был связан с NIC. Мы не смогли найти способ привязать приложение к дополнительному адресу на сетевой карте.

Обходным решением было добавить второй сетевой адаптер в виртуальную машину, переместить вторичный IP-адрес во второй сетевой адаптер в качестве основного IP-адреса второго сетевого адаптера. В Windows нельзя использовать два шлюза по умолчанию (даже если они указывают на один и тот же адрес).

Итак, на 2-й сетевой карте мы присвоили только IP-адрес и маску подсети. Чтобы получить трафик для правильного интерфейса, мы добавили оператор маршрута в формате:

route add 4.3.2.1 mask 255.255.255.255 1.2.3.4 IF 0x10002

Если хост, с которым нам нужно было связаться, - 4.3.2.1, локальный шлюз по умолчанию - 1.2.3.4, а второй сетевой адаптер отображается в таблице маршрутизации как номер интерфейса 0x10002 (из печати маршрута).

Надеюсь, это поможет. У меня есть еще несколько седых волос из-за этого.

0 голосов
/ 16 июля 2010

Похоже, таблицы маршрутизации немного запутаны на сервере для того, что вы хотите сделать.Вместо того, чтобы пытаться исправить это в приложении, настройте метрики интерфейса и / или таблицы маршрутизации на машине, чтобы они предпочли внутренний интерфейс трафику, предназначенному для этой сети. Здесь - старая ссылка, но она должна быть более или менее действительной.

Я не думаю, что .NET-сокеты позволят вам явно выбрать исходный интерфейс - самым близким будет DontRoute SocketOption, но даже там вам, вероятно, придется свернуть пользовательскую привязку и транспорт дляэта опция доступна.

...