0

I currently have a WCF client that is able to do ad-hoc service discovery to find (unknown) services running on the local subnet. I would like to implement a way for the user to specify a service endpoint to use by entering a URI into a text box, and for the client to resolve this URI to an EndpointAddress, and in the process gather additional metadata about the service. Namely, I need to gather the EndpointIdentity and additional data exposed in the Extensions property of the EndpointDiscoveryBehavior.

I am trying to achieve this by using DiscoveryClient.Resolve(), but I am only receiving null for the ResolveResponse.EndpointDiscoveryMetadata property.

String Address = "net.tcp://machine-name:12345/MyService"
DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
var criteria = new ResolveCriteria()
{
    Address = new EndpointAddress(Address)
};
var result = discoveryClient.Resolve(criteria);
//scv is null here.....
var svc = result.EndpointDiscoveryMetadata;

I've found a lot of information out there regarding DiscoveryClient.Find(), but not so much about DiscoveryClient.Resolve().

So my questions are:

  • Is this the intended use of DiscoveryClient.Resolve()?
  • Is MetadataResolver more appropriate here?
  • How does one resolve an URI to a EndpointAddress and obtain other metadata?
Josh
  • 77
  • 1
  • 12
  • try the mex endpoint net.tcp://machine-name:12345/MyService/mex – YK1 May 18 '13 at 20:07
  • So I tried specifying the mex address instead, and do get a `ResolveResponse` containing an endpoint. Problem is the endpoint is the mex endpoint and not the service endpoint. On a hunch just now, I tried specifying the EndpointIdentity in my resolve criteria, and it works! but the problem now is that I cannot know the SPN at runtime. Using `Find()` you do not need this information in advance, but using `Resolve` it seems you need to know the SPN? – Josh May 18 '13 at 20:50
  • my thought is that you should find information about service endpoint in the mex endpoint – YK1 May 18 '13 at 21:03
  • The mex endpoint does not have an `EndpointIdentity` (it is null), while the endpoint for the actual service has an SPN `EndpointIdentity`. I can't get the identity of the service through mex it seems, and the resolve method seems to need an exact match of the `EndpointAddress` in the resolve criteria. I can get my extension data from either endpoint it seems, so it seems like the problem is now reduced to finding out the identity of the service. Would it be acceptable to publish this information in the mex extensions, or is this bad practice? – Josh May 18 '13 at 21:30
  • if you create proxy to your service using svcutil.exe does it have spn identity in the client configuration? – YK1 May 18 '13 at 21:53
  • I'm doing everything in code, not using the config files. I also have to manually set the SPN in code, as it is not set automatically by WCF. I generate the SPN at runtime when starting the service to be essentially "MyService\MachineName" (where MachineName is the actual machine name). My architecture is such that I have multiple machines exposing the service on the network, and my client utilizes these services simultaneously to distribute work across (i.e. paralleling jobs within a batch). – Josh May 18 '13 at 22:20
  • I understand - only motive behind mentioning svcutil.exe was to emphasize service identity is already published and available in metadata. – YK1 May 18 '13 at 22:24

2 Answers2

1

I think you are trying to replicate functionality of svcutil.exe. In that case you may have to resolve the mex endpoint first and query service metadata from that endpoint (IMetaDataExchange). The SPN identity should be in the metadata. Also see reference http://msdn.microsoft.com/en-us/library/ms733130.aspx

YK1
  • 7,327
  • 1
  • 21
  • 28
  • So I also specified the identity of the service for the mex endpoint, but that doesn't really solve the problem. The reference you cited says "At design time, a client developer determines the server's identity through its metadata", but I can't know the identity at design time. To connect to the mex endpoint, I also need to know the identity. It seems like a chicken and egg problem. – Josh May 18 '13 at 22:35
  • You have serviceidentity for the Mex endpoint too? not sure if that's right thing to do. – YK1 May 18 '13 at 22:43
  • I originally didn't have it that way, the identity was null. I tried adding it to see if there was special authentication treatment for mex endpoints. I guess not. So the only way I'm seeing now to retrieve the identity for the service endpoint is to expose the identity through an extension on the mex endpoint. Is this kosher? – Josh May 18 '13 at 22:51
  • i think you can get actual endpoints serviceidentity from metadata itself - no need to anything. For mex endpoint see this - http://msdn.microsoft.com/en-us/library/ms733114.aspx – YK1 May 18 '13 at 22:54
1

I achieved what I wanted to do like so:

String Address = "net.tcp://machine-name:12345/MyService"
DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
var endpoint = new EndpointAddress(new Uri(Address));
var criteria = new ResolveCriteria()
{
    Address = endpoint
};
var result = discoveryClient.Resolve(criteria);

var mexClient = new MetadataExchangeClient(MetadataExchangeBindings.CreateMexTcpBinding());
var contracts = new List<ContractDescription>() { ContractDescription.GetContract(typeof(RuntimeService.Services.IWorkflowService)) };
var metaResult = MetadataResolver.Resolve(contracts, endpoint, mexClient);

var svc = metaResult.First();

I am able to get to the extension data through result and svc provides me with the correct EndpointAddress complete with the correct identity.

Thanks to @YK1 for pushing me in the right direction.

Josh
  • 77
  • 1
  • 12