In .NET 4, you can use the System.ServiceModel.Discovery.DiscoveryClient
class to find all the endpoints on the network that implement the
interface you’re looking for. Once you bind to an address, use of the
service’s proxy class is the same as before.
Implement Discoverable Host
The code for the host is exactly the same:
using System;
using System.ServiceModel;
namespace WCFDiscoverableHost
{
class Host
{
static void Main(string[] args)
{
Console.WriteLine("FileService Host (Discoverable)");
using (ServiceHost serviceHost = new
ServiceHost(typeof(FileServiceLib.FileService)))
{
serviceHost.Open();
Console.ReadLine();
}
}
}
}
The configuration has a few new items in it, however:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="FileServiceLib.FileService"
behaviorConfiguration="fileservice">
<endpoint address=""
binding="netTcpBinding"
contract="FileServiceLib.IFileService"
behaviorConfiguration="dynEPBehavior"/>
<endpoint name="udpDiscovery" kind="udpDiscoveryEndpoint"/>
<endpoint address="mex"
binding="mexTcpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8080/FileService"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="fileservice">
<serviceMetadata />
<serviceDiscovery />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="dynEPBehavior">
<endpointDiscovery />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Implement Dynamic Client
To keep the code concise, this client will also be implemented as console application.
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Discovery;
namespace WCFDiscoverableClient
{
class Client
{
static void Main(string[] args)
{
DiscoveryClient client =
new DiscoveryClient(new UdpDiscoveryEndpoint());
//find all the endpoints available
//-- you can also call this method asynchronously
FindCriteria criteria =
new FindCriteria(typeof(FileServiceLib.IFileService));
FindResponse response = client.Find(criteria);
//bind to one of them
FileServiceClient svcClient = null;
foreach (var endpoint in response.Endpoints)
{
svcClient = new FileServiceClient();
svcClient.Endpoint.Address = endpoint.Address;
break;
}
//call the service
if (svcClient != null)
{
string[] dirs = svcClient.GetSubDirectories(@"C:\");
foreach (string dir in dirs)
{
Console.WriteLine(dir);
}
}
Console.ReadLine();
}
}
}
The configuration is simpler:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<endpoint name="fileServiceEndpoint"
address=""
binding="netTcpBinding"
contract="IFileService"/>
<endpoint name="udpDiscoveryEndpoint"
kind="udpDiscoveryEndpoint"/>
</client>
</system.serviceModel>
</configuration>