8

I have a remote WCF web service that I'm connecting to from my application.

The application may be running on a server with multiple IP addresses (or multiple physical network interfaces)

I need to make sure that I can control which IP address is being used for the outbound request, instead of just using the 'preferred' interface as per the normal metric rules.

The reason for this is that multiple copies of the software will be running on the same machine, each bound to a specific IP address for its own operations, and the remote service being connected to needs to know which one is being used to connect back to it at a later time (since getting the address wrong means connecting to the wrong service)

With legacy ASMX services this is done by overriding GetWebRequest(Uri uri) on the partial class generated for the service. But I cannot figure out at all how to do this with WCF.

On an unrelated SO post, MVP @JohnSaunders suggested this may be possible by taking over the entire transport mechanism used by WCF. But I've not yet figured out how to do this either.

Community
  • 1
  • 1
PhonicUK
  • 13,486
  • 4
  • 43
  • 62
  • How about http://stackoverflow.com/questions/3249846/specify-the-outgoing-ip-address-to-use-with-wcf-client – Brad Christie Jul 09 '13 at 15:41
  • @BradChristie The first answer is OS level, the second answer doesn't apply to WCF and only applies to raw SOAP requests, hence why that question doesn't have an accepted answer. – PhonicUK Jul 09 '13 at 16:19
  • 2
    BTW, depending on the IP address to decide which instance to connect to is ... a suboptimal solution. – John Saunders Jul 12 '13 at 15:36
  • did you check [this link](http://vunvulearadu.blogspot.com/2013/03/wcf-client-and-multiply-ip-address-how.html) – Mahmoud Darwish Jul 15 '13 at 05:24
  • _"the remote service being connected to needs to know which [IP address] is being used to connect back to it at a later time"_ - to me, but please correct me if I'm wrong, this looks like you're trying to solve an architecture issue at a too low level, if even possible. Doesn't this ask for duplex channels, or can't you let the clients poll the remote webservice instead of letting the call back the clients? – CodeCaster Jul 16 '13 at 11:16
  • @CodeCaster this is server<->server software so to speak instead of what anyone would think of as a 'client' being involved. And the system talking back to the 'clients' may not be the one the 'clients' are connecting to in the first place. – PhonicUK Jul 16 '13 at 11:29
  • So, this is not really about selecting IP addresses for the TCP channel, is it? If you want to send information to the service to say "when you send a reply, send it _here_" that is a *Duplex* system, something quite different. – Paul Turner Jul 17 '13 at 15:00

3 Answers3

4

This is a tricky problem, which WCF doesn't seem to cater for particularly well.

The only component in the .NET framework that seems to directly deal with the issue of the client address is the ServicePoint class. Specifically, it has a BindIPEndPointDelegate property which lets you control how it selects the client IP. The documentation for the property includes this:

Some load balancing techniques require a client to use a specific local IP address and port number, rather than IPAddress.Any (or IPAddress.IPv6Any for Internet Protocol Version 6) and an ephemeral port. Your BindIPEndPointDelegate can satisfy this requirement.

Thus, you should be able to modify the service point associated with your URL in code like this:

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

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

Obviously this kind of code requires your classes have awareness of the protocol and the endpoint address the client will be communicating with. It would likely be most appropriate to set up this logic as a client behaviour which can be applied to your client channel.

Paul Turner
  • 38,949
  • 15
  • 102
  • 166
  • 1
    I'm assuming that you're using HTTP, since you mentioned ASMX services. This solution only works for the HTTP protocol, as ServicePointManager only deals with that stack. – Paul Turner Jul 17 '13 at 09:03
0

you can use a message property (HttpRequestMessageProperty) to add HTTP headers to any outgoing requests. You need to create a "scope" in which the property will be added to the current "operation context", and attach the property, with all headers you want, to the outgoing message properties of the context.

please look at this :

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

Mostafa Soghandi
  • 1,524
  • 1
  • 12
  • 20
0

Use this: New Class:

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

And now is something like this:

YourService us = new YourService();
us.Url = us.ApplyServerURL();
Nițu Alexandru
  • 714
  • 1
  • 11
  • 33