简体   繁体   中英

Add Discovery to my WCF service

I have WCF service how run on 1 machine and simple comsole application client who run on another machine. the server do something very simple: one method that return the value of 2 number that the client sent:

[ServiceContract]
public interface IMySampleWCFService
{
    [OperationContract]
    int Add(int num1, int num2);

    [OperationContract]
    void CreateDirectory(string directory);

    [OperationContract]
    string GetVendorToRun(string path);
}

    public class MySampleWCFService : IMySampleWCFService
    {
        public int Add(int num1, int num2)
        {
            return num1 + num2;
        }
    }

App.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <system.web>
    <compilation debug="true" />
  </system.web>
  <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <services>
      <service name="WCFServiceHostingInWinService.MySampleWCFService">
        <endpoint
          name="ServiceHttpEndPoint"
          address="" 
          binding="basicHttpBinding"
          contract="WCFServiceHostingInWinService.IMySampleWCFService">
        </endpoint>
        <endpoint
          name="ServiceMexEndPoint"
          address="mex"
          binding="mexHttpBinding"
          contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://192.0.16.250:8733/MySampleWCFService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the value below to false before deployment -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

</configuration>

What i want to do and find it hard to implement because i am a new developer is add Discovery to my WCF service , suppose i have several services that installed on several machines, what the client application is open i want to now which services is alive\\running and all this data that i can received from Discovery. I try to read several articles but as i mention didn't understand how to do it and I would love some help.

Using WCF Discovery is a bit convoluted and few people actually use it in my experience but it does work. This MSDN article has all the detail needed for adding Discovery to both the service & client configuration files.

The premise behind WCF Discovery is that you a expose a new discovery endpoint in similar way to the default MEX endpoint. The MEX endpoint allows the service to provide WSDL to clients. A WCF Discovery endpoint exposes a configured service to clients by means of UDP based responses to client UDP based requests. The overview link above provides much more detail.

Here is how your service configuration would look like:

<system.serviceModel>
    <services>
      <service name="WCFServiceHostingInWinService.MySampleWCFService">
        <endpoint
          name="ServiceHttpEndPoint"
          address="" 
          binding="basicHttpBinding"
          contract="WCFServiceHostingInWinService.IMySampleWCFService"
          behaviorConfiguration="endpointDiscoveryBehavior">
        </endpoint>
        <endpoint
          name="ServiceMexEndPoint"
          address="mex"
          binding="mexHttpBinding"
          contract="IMetadataExchange" />
        <!-- Discovery Endpoint: -->
        <endpoint kind="udpDiscoveryEndpoint" />
        <host>
          <baseAddresses>
            <add baseAddress="http://192.0.16.250:8733/MySampleWCFService/" />
          </baseAddresses>
        </host>
      </service>
      <!-- Announcement Listener Configuration -->
      <service name="AnnouncementListener">
        <endpoint kind="udpAnnouncementEndpoint" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the value below to false before deployment -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="True" />
          <serviceDiscovery>
            <announcementEndpoints>
              <endpoint kind="udpAnnouncementEndpoint"/>
            </announcementEndpoints>
          </serviceDiscovery>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="endpointDiscoveryBehavior">
          <endpointDiscovery enabled="true"/>
        </behavior>
     </endpointBehaviors>
    </behaviors>
</system.serviceModel>

I think the most easy way to do this is to try to connect your client to addresses that you calculate at the runtime. For example:

    static void Main(string[] args)
    {
        var addresses = new List<string>
        {
            @"http://192.168.1.1:8730/MySampleWCFService/",
            @"http://localhost:8731/MySampleWCFService/",
            @"http://localhost:8732/MySampleWCFService/",
            @"http://localhost:8733/MySampleWCFService/",
        };
        foreach (var address in addresses)
        {
            var client = new MySampleWCFServiceClient(new BasicHttpBinding(), new EndpointAddress(address));
            try
            {
                client.Open();
                client.Add(0, 1);
                Console.WriteLine("Connected to {0}", address);

            }
            catch (EndpointNotFoundException)
            {
                Console.WriteLine("Service at {0} is unreachable", address);
            }
        }
        Console.ReadLine();
    }

In my case I create a list with addresses but in your case you may build addresses with some predefined rules. For example you know that services use http binding with some name and port. Also you know that your cluster is in 192.0.16.xxx LAN so you may use formula:

address = "http://" + NextLanAddress() + ":" + port + "/" + serviceName + "/";

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM