在LAN中搜索WCF服务?

时间:2009-03-09 14:26:03

标签: c# .net wcf

有没有办法在本地网络的任何一台计算机中搜索给定WCF服务的存在?

例如,我正在寻找Math / Add2Numbers服务,我想知道局域网上的哪些机器提供它,有没有办法做到这一点?

3 个答案:

答案 0 :(得分:4)

这是一个超级简单的发现示例。它不使用配置文件,它都是c#代码,但您可以将概念移植到配置文件中。

在主机和客户端程序之间共享此接口(暂时复制到每个程序)

[ServiceContract]
public interface IWcfPingTest
{
  [OperationContract]
  string Ping();
}

将此代码放入主程序

public class WcfPingTest : IWcfPingTest
{
  public const string magicString = "djeut73bch58sb4"; // this is random, just to see if you get the right result
  public string Ping() {return magicString;}
}
public void WcfTestHost_Open()
{
  string hostname = System.Environment.MachineName;
  var baseAddress = new UriBuilder("http", hostname, 7400, "WcfPing");
  var h = new ServiceHost(typeof(WcfPingTest), baseAddress.Uri);

  // enable processing of discovery messages.  use UdpDiscoveryEndpoint to enable listening. use EndpointDiscoveryBehavior for fine control.
  h.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
  h.AddServiceEndpoint(new UdpDiscoveryEndpoint());

  // enable wsdl, so you can use the service from WcfStorm, or other tools.
  var smb = new ServiceMetadataBehavior();
  smb.HttpGetEnabled = true;
  smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
  h.Description.Behaviors.Add(smb);

  // create endpoint
  var binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
  h.AddServiceEndpoint(typeof(IWcfPingTest) , binding,   "");
  h.Open();
  Console.WriteLine("host open");
}

将此代码放入客户端程序

private IWcfPingTest channel;
public Uri WcfTestClient_DiscoverChannel()
{
  var dc = new DiscoveryClient(new UdpDiscoveryEndpoint());
  FindCriteria fc = new FindCriteria(typeof(IWcfPingTest));
  fc.Duration = TimeSpan.FromSeconds(5);
  FindResponse fr = dc.Find(fc);
  foreach(EndpointDiscoveryMetadata edm in fr.Endpoints) 
  {
    Console.WriteLine("uri found = " + edm.Address.Uri.ToString());
  }
  // here is the really nasty part
  // i am just returning the first channel, but it may not work.
  // you have to do some logic to decide which uri to use from the discovered uris
  // for example, you may discover "127.0.0.1", but that one is obviously useless.
  // also, catch exceptions when no endpoints are found and try again.
  return fr.Endpoints[0].Address.Uri;  
}
public void WcfTestClient_SetupChannel()
{
  var binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
  var factory = new ChannelFactory<IWcfPingTest>(binding);
  var uri = WcfTestClient_DiscoverChannel();
  Console.WriteLine("creating channel to " + uri.ToString());
  EndpointAddress ea = new EndpointAddress(uri);
  channel = factory.CreateChannel(ea);
  Console.WriteLine("channel created");
  //Console.WriteLine("pinging host");
  //string result = channel.Ping();
  //Console.WriteLine("ping result = " + result);
}
public void WcfTestClient_Ping()
{
  Console.WriteLine("pinging host");
  string result = channel.Ping();
  Console.WriteLine("ping result = " + result);
}

在主机上,只需调用WcfTestHost_Open()函数,然后永远睡眠或其他东西。

在客户端上运行这些功能。主机需要一段时间才能打开,所以这里有几个延迟。

System.Threading.Thread.Sleep(8000);
this.server.WcfTestClient_SetupChannel();
System.Threading.Thread.Sleep(2000);
this.server.WcfTestClient_Ping();

主机输出应该看起来像

host open

客户端输出应该看起来像

uri found = http://wilkesvmdev:7400/WcfPing
creating channel to http://wilkesvmdev:7400/WcfPing
channel created
pinging host
ping result = djeut73bch58sb4

这是我能想出的最小发现示例。这些东西变得非常复杂。

答案 1 :(得分:2)

您需要的是WS-Discovery,但不幸的是,这不包含在WCF中的ws- *扩展中。它有一些自行开发的实现。这是一个google search

否则,您可以由第三方供应商(如IBMMicrosoft)实施企业UDDI或注册表解决方案。

答案 2 :(得分:0)

您可以使用UDDI来查找它,但如果有多个服务实例,您将如何决定使用哪个实例?