WCF Discovery simply doesn't work

后端 未结 2 1378
暖寄归人
暖寄归人 2021-02-01 07:15

I\'m trying to add ad-hoc discovery to a simple WCF service-client setup (currently implemented by self hosting in a console app). Debugging using VS2010 on windows 7, and doing

相关标签:
2条回答
  • 2021-02-01 07:50

    Damn! it was the firewall... for some reason all UDP communication was blocked - disabling the firewall solved the problem. Now I only need to figure out the correct firewall configuration...

    0 讨论(0)
  • 2021-02-01 08:12

    Here is a super simple discovery example. It does not use a config file, it is all c# code, but you can probably port the concepts to a config file.

    share this interface between host and client program (copy to each program for now)

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

    put this code in the host program

    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");
    }
    

    put this code in the client program

    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);
    }
    

    on the host, simply call the WcfTestHost_Open() function, then sleep forever or something.

    on the client, run these functions. It takes a little while for a host to open, so there are several delays here.

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

    host output should look like

    host open
    

    client output should look like

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

    this is seriously the minimum I could come up with for a discovery example. This stuff gets pretty complex fast.

    0 讨论(0)
提交回复
热议问题