2011-07-21 7 views
14

Sto cercando di aggiungere il rilevamento ad-hoc a una semplice configurazione del client-servizio WCF (attualmente implementata da self hosting in un'app console). Eseguire il debugging con VS2010 su Windows 7 e fare tutto ciò che posso trovare nel tutorial online, ma ancora - il client di scoperta non trova nulla. Inutile dire che se apro un client all'endpoint del servizio corretto posso accedere al servizio dal client.WCF Discovery semplicemente non funziona

codice di servizio:

using (var selfHost = new ServiceHost(typeof(Renderer))) 
{ 
    try 
    { 
     selfHost.Open(); 
     ... 
     selfHost.Close(); 

servizio app.config:

<?xml version="1.0"?> 
<configuration> 
    <system.serviceModel> 
    <services> 
     <service name="TestApp.Renderer"> 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://localhost:9000" /> 
      </baseAddresses> 
     </host> 
     <endpoint address="ws" binding="wsHttpBinding" contract="TestApp.IRenderer"/> 
     <endpoint kind="udpDiscoveryEndpoint"/> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <serviceDiscovery/> 
      <serviceMetadata httpGetEnabled="True"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 
</configuration> 

cliente codice scoperta:

DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint()); 
var criteria = new FindCriteria(typeof(IRenderer)) { Duration = TimeSpan.FromSeconds(5) }; 
var endpoints = discoveryClient.Find(criteria).Endpoints; 

La collezione 'endpoint' viene sempre fuori vuoto. Ho provato a eseguire il servizio e il client dal debugger, da una riga di comando, da una riga di comando dell'amministratore - tutto, ma senza alcun risultato (tutto sul computer locale, ovviamente, non a gestione avrò bisogno che funzioni su tutta la mia sottorete eventualmente)

Qualsiasi aiuto sarebbe apprezzato :-)

+0

Ho anche provato ad aggiungere un annuncio endpoint nel servizio. Il comportamento di Discovery, anche questo non ha aiutato – kbo

+0

ci sono informazioni app.config per il client? –

+0

hai anche provato ad aggiungere un ambito? –

risposta

3

Dannazione! era il firewall ... per qualche ragione tutte le comunicazioni UDP erano bloccate - disabilitare il firewall risolveva il problema. Ora ho solo bisogno di capire la corretta configurazione del firewall ...

+0

hai mai capito come configurare il firewall? Sto avendo lo stesso problema. – odyth

+1

Sì Discovery fa affidamento sugli attacchi UDP per individuare i servizi –

35

Ecco un super semplice esempio scoperta. Non usa un file di configurazione, è tutto il codice C#, ma probabilmente puoi portare i concetti in un file di configurazione.

parti questa interfaccia tra host e programma client (copia a ciascun programma per ora)

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

inserire questo codice nel programma host

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

inserire questo codice nel programma client

sull'host, è sufficiente chiamare la funzione WcfTestHost_Open(), quindi dormire per sempre o qualcosa.

sul client, eseguire queste funzioni. Ci vuole un po 'prima che un host si apra, quindi ci sono diversi ritardi qui.

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

uscita ospite dovrebbe assomigliare

host open 

uscita cliente dovrebbe essere simile

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

questo è seriamente il minimo che potevo venire con un esempio, la scoperta. Questa roba diventa abbastanza complessa velocemente.

+4

Ottimo post. Adoro gli esempi minimi di tutti i codici per WCF! – Peladao

1

Poiché questa è la prima risposta StackOverflow.com che emerge quando ho cercato "WCF Discovery", suggerirei l'esempio IDesign Juval Lowy: Ad-hoc Discovery. È un eccellente esempio di Discovery WCF che utilizza sia UdpDiscoveryEndpoint che MEX. Se non hai familiarità con IDesign o Juval Lowy, suggerirei anche questo MSDN link.