Archived

This forum has been archived. Please start a new discussion on GitHub.

server discovery

I'm new to the Ice world and I'm trying to understand whether Ice can help me in the following scenario:

I have a number of Ice based process, all equal (i.e.: all run the same code) which are randomly scattered on some servers on the same LAN. You can imagine a number of database servers each providing its own set of data. Each process has its own identification name.

I'd like a client to be able to connect to any of the process by specifying its name independently on the IP address of the node where the server is running. Because I'd like to be able to start more than one process on a single workstation, even the IP port must be dinamically assigned to avoid conflict.

In a world without Ice I would provide the server process with a thread waiting for broadcasts and design a small protocol to allow a client to broadcast a discovery request end receive a reply from the selected server with connection information. Yes, this is very like to ARP ;-)

Does the Ice framework provide feature to support the above?

Many thanks for any reply.

Luca

Comments

  • mes
    mes California
    Hi Luca,

    There are several ways you could do this with Ice.

    First, you could use multicast. This would involve creating an object adapter with a multicast UDP endpoint on which all servers listen for "server discovery" broadcasts.

    The second approach would use IceGrid. You may not need all of the capabilities that IceGrid provides, such as the ability to launch servers automatically. However, IceGrid also includes a lookup mechanism for locating well-known objects using only their identities. Each of your clients and servers must be statically configured with the address of the IceGrid "locator", but no other static addressing information is required.

    Finally, if you do not want to use IceGrid, you could implement your own custom "locator" facility. Ice defines a standard interface for this facility, of which IceGrid is just one implementation.

    Hope that helps.

    Regards,
    Mark
  • Thank you very much for your reply. I can add that while looking around for some example code on how to use multicast, I found the very answer to my question in ../Ice-3.4.2-demos/demo/Ice/multicast (the demo directory which comes with Ice)

    Cheers,
    Luca
    mes wrote: »
    Hi Luca,

    There are several ways you could do this with Ice.

    First, you could use multicast. This would involve creating an object adapter with a multicast UDP endpoint on which all servers listen for "server discovery" broadcasts.

    The second approach would use IceGrid. You may not need all of the capabilities that IceGrid provides, such as the ability to launch servers automatically. However, IceGrid also includes a lookup mechanism for locating well-known objects using only their identities. Each of your clients and servers must be statically configured with the address of the IceGrid "locator", but no other static addressing information is required.

    Finally, if you do not want to use IceGrid, you could implement your own custom "locator" facility. Ice defines a standard interface for this facility, of which IceGrid is just one implementation.

    Hope that helps.

    Regards,
    Mark
  • multicast when server has several network interfaces

    I've successfully used the example code in Ice-3.4.2-demos/demo/Ice/multicast to implement my server discovery mechanism. Thanks again for the hints.

    Now I have a more tricky problem. While testing my code I noticed that if the machine running the server has more than one network interface configured, the client took from 0 to 3 minutes to connect, at random. This is well reproducible also with the client/server test programs quoted above.

    Referring to the code in Client.cpp of the quoted demo, the delay was in the call:

    HelloPrx hello = HelloPrx::checkedCast(base);

    By setting Ice.Trace.Network I was able to understand why. When calling uncheckedCast() I could see attempts to establish connection to all the IP numbers of network interfaces configured on the server machine. Of course only one of the IP numbers could reply (because the others are on different LANs). Each unsuccessful attempt caused a timeout of 60 sec.

    To solve this problem I think I could send back to the client not an object proxy (as in the example code) but the IP/port info which the client can use to create the proxy.

    What I do not know is how the server can derive from the call to DiscoverI::lookup() the IP number of the interface from which the call has arrived
  • bernard
    bernard Jupiter, FL
    Hi Luca,

    The solution is to use "-h <name or IP address>" in your object adapter Endpoints configuration.

    This -h <name or IP address> designates the network interface that you want to use on your server: your object adapter will listen only on this interface, and proxies created using this object adapter (and returned to your client) will include only an endpoint with this name or address.

    Without this -h in the Endpoints configuration, your object adapter listens all your network interfaces, and by default creates proxies that contain endpoints for all these network interfaces, except localhost ... and then your client gets proxies with endpoints it can't use.

    See Object Adapter Endpoints - Ice 3.4 - ZeroC and Proxy and Endpoint Syntax - Ice 3.4 - ZeroC for complete details.

    Best regards,
    Bernard
  • Many thanks for the reply. But your proposed solution does not fit well with my needs: from one side I'd like the server to be able to reply on all the interfaces, and moreover if I make an "interface aware" server I've got to provide a configure item or a start argument with the interface address/name.

    In the meanwhile I think I have a viable solution (not yet tested, but should work): I will modify the DiscoverReply interface so that the argument to the reply() method is not an Object, but some info needed to create the proxy (thanks for transparent proxies in Ice!), i.e.: a string for the identity and a port number.

    At the client side when I get the call to reply() I can extract the senderAddress from the Ice::Current argument and I have all I need to create my proxy.