سؤال

I have a WCF server library and client[Winform], i launch the server using a self-host winform.

I want to let client to discover the active servers on LAN, in another way to get online servers IPAddresses in a list. i tried DiscoveryClient and UdpDiscoveryEndpoint and it worked this's the code :

Client[Winform] :

 private void button1_Click(object sender, EventArgs e)
    {
        DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
        FindResponse findResponse = discoveryClient.Find(new FindCriteria(typeof(IFileManager)));
        foreach (EndpointDiscoveryMetadata ep in findResponse.Endpoints)
        {
            listView1.Items.Add(ep.Address.ToString());
        }
    }   

Server[Winform] :

ServiceHost host = new ServiceHost(typeof(MainService));
private void button1_Click(object sender, EventArgs e)
    {
        if (button1.Text == "Start")
        {
            host.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
            host.AddServiceEndpoint(new UdpDiscoveryEndpoint());
            host.Open();
            button1.Text = "Stop";
        }
        else
        {
            host.Close();
            button1.Text = "Start";
        }
    }

but it didn't work like i expect it!

  • Why do i have to give a specific Criteria to ClientDiscovery ? i have many interfaces, i just need the host address, not the address of the interface!
  • it takes too much time [about 15-20s] to get the list, isn't suppose to be fast?

    UPDATE:
    I've developed a server discovery on TCP sockets before i used WCF, i used parallel threading that try/catch to connect and loop over 255 IPAddresses ex: (192.168.1.X), i tried it on LAN 5 servers[PC], the result was so perfect and fast , i sat a timeout (3 sec)
    but on WCF i dont know how would i accomplish this !!

    enter image description here

  • هل كانت مفيدة؟

    المحلول

    Why do i have to give a specific Criteria to ClientDiscovery ? i have many interfaces, i just need the host address, not the address of the interface!

    That is the point of decoupling, the fact that all services that you need are on a single server is an implementation detail. That said, you could couple your client to your particular architecture, manually creating clients with the info from the MEX address received from the first result of the discovery process.

    it takes too much time [about 15-20s] to get the list, isn't suppose to be fast?

    No, discovery is not supposed to be fast if you are looking for multiple instances of a service: the default timeout is 20s. Now, if you need only 1 instance of that service (which is most of the time), then you could tell the client explicitly to stop after finding the first service, by setting the MaxResults property of FindCriteria to 1. That is way faster than waiting for the timeout.

    For further information you can check this excellent article.

    UPDATE

    You can set the timeout via the FindCriteria.Duration property.

    UPDATE 2

    All the information you can get about the service is through the MEX endpoint. You could use a MetadataExchangeClient with the MEX address you get from the discovery and make use of the info in the MetadataSet you get back (see http://msdn.microsoft.com/en-us/library/ms730243.aspx, Retrieving Service Metadata), but I don't know for sure what kind of information you will get back since I never used it this way.

    It depends on what you mean by status: WS-discovery has no concept of status that I'm aware of, either the service is there or not. Any other interpretation of this concept you have to implement yourself as an operation in your services.

    نصائح أخرى

    If you use the DiscoveryClient's FindAsync() method with the FindProgressChanged and FindCompleted events rather than the synchronous Find() method, you'll find that the FindProgressChanged event is fired as soon as the endpoint results come in, meaning you'll have access to them immediately instead of having to wait to the end of the search. You'll know the search is over when FindCompleted fires.

    For me, it doesn't take more than a few seconds before all my network's clients have reported in through the FindProgressChanged event using this method.

    Oh, and if you need to cancel your search for any reason (somebody closed your dialog in the middle of the search, for instance), then call the DiscoveryClient's CancelAsync() method.

    مرخصة بموجب: CC-BY-SA مع الإسناد
    لا تنتمي إلى StackOverflow
    scroll top