Endpoint addresses are actually on service replicas and instances - those are the things that are actually placed on nodes. There is a special method for this in the ServiceManagerClient called ResolveServicePartitionAsync.
In the Reliable Services SDK (in the Microsoft.ServiceFabric.Services.Client namespace) we provide a resolver utility that makes this a bit easier:
ServicePartitionResolver resolver = ServicePartitionResolver.GetDefault();
ResolvedServicePartition partition =
await resolver.ResolveAsync(new Uri("fabric:/MyApp/MyService"), new ServicePartitionKey(), cancellationToken);
The Endpoints property of ResolvedServicePartition is a list of each replica/instance in the partition. The Address property will contain a JSON object, which is a list of key-value pairs containing each listener that's opened by the replica/instance:
{
"Endpoints" :
{ "mylistener1" : "some-address" },
{ "mylistener2" : "some-address" }
...
}
Keep in mind that there's no guaranteed order for when replicas/instances come up, so you may need to retry a few times. Also, replicas and instances will move at times throughout the service's lifetime, so you'll need to keep the list up to date. Basically you can't really just get all this information up front in one go and be set because it's a very dynamic system.
See here for an overview:
https://azure.microsoft.com/en-us/documentation/articles/service-fabric-connect-and-communicate-with-services/
And here for more detailed information: https://azure.microsoft.com/en-us/documentation/articles/service-fabric-reliable-services-communication/