Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF Discovery .NET 4: Problem with config / programmatically definition

i have a discovery enabled WCF service and now i want to connect the client to it.

Problem: When i use the udp endpoint ( 1. ) and try to programmatically discover the service, it works... When i use the App.config approach ( 2. ) it does not ( Error: No endpoints discovered ).

To me it seems the "udp discovery result" of both of the solutions should be the same, but unfortunately it isn't...

1. Programmatically approach (works ):

Code:

        DiscoveryClient discClient = new DiscoveryClient("udpDiscoveryEndpoint");
        FindCriteria fCriteria = new FindCriteria(typeof(IAlarmServer));
        fCriteria.Duration = TimeSpan.FromSeconds(5);
        fCriteria.MaxResults = 1;
        FindResponse fResponse = discClient.Find(fCriteria);

        EndpointAddress address = fResponse.Endpoints[0].Address;
        Console.WriteLine("Address found: " + address.ToString());

Config:

<system.serviceModel>
  <client>
     <endpoint name="udpDiscoveryEndpoint" kind="udpDiscoveryEndpoint" />
  </client>
</system.serviceModel>

2. Approach with App.config and "integrated into endpoint" approach (does not work!):

Code:

        var Proxy = new AlarmServerClient("IAlarmServer"); // Default client generated by Visual Studio
        Proxy.SomeMethod(); // throw no endpoints discovered exception

Config:

<standardEndpoints>
  <dynamicEndpoint>
    <standardEndpoint name="discoveryDynamicEndpointConfiguration">
      <discoveryClientSettings>
        <findCriteria duration="00:00:05" maxResults="1">
          <types>
            <add name="AlarmServiceRef.IAlarmServer"/>
          </types>
        </findCriteria>
        <endpoint kind="udpDiscoveryEndpoint"/>
      </discoveryClientSettings>
    </standardEndpoint>
  </dynamicEndpoint>
</standardEndpoints>

Config:

  <client>
     <endpoint binding="basicHttpBinding" bindingConfiguration="DefaultBasicHttpBinding" contract="AlarmServiceRef.IAlarmServer" name="IAlarmServer"
            kind="dynamicEndpoint"
            endpointConfiguration="discoveryDynamicEndpointConfiguration"/>
  </client>

Any ideas why this is happening?

like image 885
David Avatar asked May 23 '11 13:05

David


1 Answers

Couple of things when you're hosting a service with discovery via IIS

  1. In the service configuration make sure the service name matches the class name including the namespace
  2. You have to make sure the service is running before you can discover it with a client. You can manually browse to the service's .svc file or host the service with AppFabric and set AutoStart to true (You can also specify that in the web.config)
  3. In the service configuration you have to emit the type you're going to use in the find criteria on the client

Here is a sample of the server configuration setting up the service endpoints. Note that the service "name" attribute is the full namespace to the class that is implementing the service.

Service Config

<services>
      <service name="WcfDiscovery.Services.BuzzerService" behaviorConfiguration="sb1" >
        <endpoint binding="basicHttpBinding" contract="WcfDiscovery.Contracts.IAlarmServer" address="" behaviorConfiguration="eb1"  />
        <endpoint kind="udpDiscoveryEndpoint"  />
      </service>
    </services>

Also make sure to add the discovery behavior to the service

Service Config

<serviceBehaviors>
        <behavior name="sb1">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
          <serviceDiscovery />
        </behavior>
      </serviceBehaviors>

Since I want clients to be able to discover the service by the type (WcfDiscovery.Contracts.IAlarmServer) I have to also specify that in the behavior configuration for the endpoint (eb1)

Service Config

<endpointBehaviors>
        <behavior name="eb1">
          <endpointDiscovery enabled="true">
            <types>
              <add name="WcfDiscovery.Contracts.IAlarmServer" />
            </types>
          </endpointDiscovery>
        </behavior>
      </endpointBehaviors>

Now on the client side I can discover the service using the findCriteria. Note that the type in the find criteria has to match the one emitted by the service (in the services types list)

Client Config

<standardEndpoints>
      <dynamicEndpoint>
        <standardEndpoint name="dynamicEndpointConfiguration">
          <discoveryClientSettings >
            <endpoint kind="udpDiscoveryEndpoint" />

            <findCriteria maxResults="2">
              <types>
                <add name="WcfDiscovery.Contracts.IAlarmServer" />
              </types>
            </findCriteria>

          </discoveryClientSettings>
        </standardEndpoint>
      </dynamicEndpoint>
    </standardEndpoints>

Here is the client endpoint configuration

Client Config

<client>
      <endpoint kind="dynamicEndpoint" name="endpoint" binding="basicHttpBinding" contract="WcfDiscovery.Contracts.IAlarmServer" endpointConfiguration="dynamicEndpointConfiguration" />
    </client>

Finally, I can discover the service in a console app like this:

ChannelFactory<IAlarmServer> factory = new ChannelFactory<IAlarmServer>("endpoint");
            var proxy = factory.CreateChannel();

            Console.WriteLine(proxy.SoundAlarm());

Hope this helps!

like image 52
JaySilk84 Avatar answered Oct 18 '22 18:10

JaySilk84