2011-07-21 10 views
14

Estoy tratando de agregar un descubrimiento ad-hoc a una configuración de cliente de servicio WCF simple (actualmente implementado por el alojamiento propio en una aplicación de consola). Depuración utilizando VS2010 en Windows 7 y haciendo todo lo que puedo encontrar en el tutorial en línea, pero aún así, el cliente de descubrimiento simplemente no encuentra nada. No hace falta decir que si abro un cliente al punto final de servicio correcto, puedo acceder al servicio desde el cliente.WCF Discovery simplemente no funciona

código de servicio:

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

servicio 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 código de descubrimiento:

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

La colección '' puntos finales siempre sale vacía. He intentado ejecutar el servicio y el cliente desde el depurador, desde una línea de comandos, desde una línea de comando de administrador; todo, pero fue en vano (todo en la máquina local, por supuesto, no para gestionarlo, lo necesitaré ejecutándolo). toda mi subred con el tiempo)

Cualquier ayuda sería muy apreciada :-)

+0

También intenté agregar un punto final de anuncio en el comportamiento del servicioDiscovery, eso tampoco ayudó – kbo

+0

¿hay alguna información de app.config para el cliente? –

+0

también ha intentado agregar un alcance? –

Respuesta

3

¡Maldición! era el servidor de seguridad ... por alguna razón, todas las comunicaciones UDP estaban bloqueadas, deshabilitar el firewall resolvió el problema. Ahora solo necesito averiguar la configuración correcta de firewall ...

+0

¿alguna vez descubrió cómo configurar el firewall? Estoy teniendo el mismo problema. – odyth

+1

Sí Discovery se basa en explosiones UDP para localizar servicios –

35

Aquí es un super ejemplo simple descubrimiento. No utiliza un archivo de configuración, es todo el código C#, pero probablemente pueda transferir los conceptos a un archivo de configuración.

cuota de esta interfaz entre el anfitrión y el programa cliente (copia a cada programa por ahora)

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

poner este código en el programa de acogida

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

poner este código en el programa cliente

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

en el host, simplemente llame a la función WcfTestHost_Open() y luego duerma siempre o algo.

en el cliente, ejecute estas funciones. El host demora un poco en abrirse, por lo que hay varias demoras aquí.

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

de salida de host debe ser similar

host open 

salida del cliente debe ser similar

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

esto es serio lo mínimo que podía llegar a un ejemplo de descubrimiento. Este material se vuelve bastante complejo rápido.

+4

Gran publicación. ¡Me encantan los ejemplos mínimos de WCF para todos los códigos! – Peladao

1

Como esta es la primera respuesta de stackoverflow.com que aparece cuando busqué 'WCF Discovery', sugiero el ejemplo de IDesign Juval Lowy: Ad-hoc Discovery. Es un excelente ejemplo de WCF Discovery utilizando un UdpDiscoveryEndpoint y MEX. Si no está familiarizado con IDesign o Juval Lowy, también le sugiero este MSDN link.

Cuestiones relacionadas