0
votes

As stated in the question, I need to handle a changing baseAddress property of a WCF service host. I have a simple object that contains a picture's binary value. This will be sent from a remote computer (actually a multitude of different ones) to the server through a Web app on the server that requests a specific file name based on given files in a database.

To do this I have made the service and implemented the necessary contracts, but I am stuck at the baseAddress element in the service's config file.

The dilemma is that the remote machine's IP is dynamic. It changes at about 5 min intervals (externally provided) and the machine is not part of a VPN or any (inter)network and has no DNS configured. It only has its pc name set. I am however able to pull the IP of this device from a table to provide to the client app with the 'correct' IP to bind to, but my issue is rather at the host side.

The question is basically - in this described host, how do I specify the baseAddress that clients will bind to? I imagine I cannot rebind every time an IP address change is detected, or would that be no issue?

I have tried specifying "http://localhost:6090/BasicService/" which was unreachable when I attempted from the client to call "http://192.168.0.4:6090/BasicService/". However when I specify the exact IP in both client and host, the client successfully contacts the host.

Note that the binding of my service is basicHttpBinding and the private IP addresses are just in a test environment. When live, these devices receive their IP from m2m providers.

EDIT: For better understanding, the remote device will be the server and contains the binding information which is XYZ and XYZ is what I am trying to figure out. The client can connect to a local machine to retrieve a specific remote device's IP and then bind the client to that given IP, but the issue is that in the host I am unsure as to what to use in the following:
host
baseAddresses
add baseAddress="http://????????:6090/"
baseAddresses
host

The suggested answer below does help when these devices are in a closed network and you call the server's private IP, but does not work with the server's public IP.

1
You are using incorrect terminology. "base address" is from the perspective of the server only, not the client. The client must always specify the full URL. stackoverflow.com/questions/2016285/… - Micky
If you are not going to use DNS then you might want to consider a fixed IP that is routed to the device on the dynamic IP. The same principle is used with load balancers or hiding computers from the Internet - Micky
"...when I specify the exact IP in ... client ..., the client successfully contacts the host" - well what did you expect? If you run the client on the actual host then you can use localhost. However, clients running on a computer different to the host can never use localhost. It seems you need an understanding of IP resolution - Micky
@MickyD I know how the IP address resolution works, the question is understood in reverse. Please see the comment I provided on the answer below. What I meant with this was that when I specify "localhoost" in the server, I thought that maybe that means that the service will host on the device's current IP. - Joandre Tait
Note that my answer is the answer to your question. Your next question should be about IP resolution, not about server bindings. - Jesse de Wit

1 Answers

-1
votes

There is some confusion about your question (see comments). In this answer I assumed your clients do know the IP address of your server, but your problem is binding the server to an unkown IP address.

Server side

In order to listen to any ip address on your server side, you could use ip address 0.0.0.0. This way, on the server side, you don't need to worry about the ip address. Like so:

<host>
  <baseAddresses>
    <add baseAddress="http://0.0.0.0:6090/BasicService" />
  </baseAddresses>
</host>

Client side

And on the client side, you can make the binding dynamic, by specifying it in code:

string ipAddress = GetIpFromTable(); // Assuming client can do this...
string url = $"http://{ipAddress}:6090/BasicService";
var binding = new BasicHttpBinding();
var address = new EndpointAddress(url);        
var client = new BasicServiceClient(binding, address);

You may run into some trouble when the ip address changes during/before a request though, so make sure you have your error handling in order and retry if the first attempt failed.