Flexible, reliable and portable service discovery

I am looking for a way that clients on the local network can find all instances of my server application without any configuration. Instead of hacking something, I would like to use an existing solution. Personally, I need this to be done in Python, but I would be happy to hear about solutions in any other language.

So why am I not using avahi or OpenSLP or some other Zeroconf / SLP solution? Well, there are a few additional criteria, and I get the impression that none of the above systems matches them.

I am looking for a solution that:

  • Flexible . It should not require superuser rights, i.e. Use only ports> 1024.
  • Solid It must allow multiple services of the same and different types of services on the same machine and continue to advertise the services, even if the instance that launched the ad server stops or fails.
  • portable . It should work almost everywhere, or at least on * BSD, Debian / gentoo / RedHat / SuSe Linux, Mac OS X, Solaris, and Windows NT.
  • Light Ideally, a single Python script would be the whole solution. I'm not at all interested in address auto-configuration or something like that, although I would love to make a decision that has a lot of features that I don't need. In addition, any one-time setup is a strict absence-no.

I expect something like this:

def registerService(service): # (type, port) if listen(multicast, someport): if fork() == child: services = [service] for q in queriesToMe(): if q == DISCOVERY: answer(filter(q.criteria, services)) elif q == ADVERTISE and q.sender == "localhost": services.append(q.service) else: advertiseAt("localhost", service) 
+4
source share
3 answers

I wrote an application / library (currently the Python interface and CLI) that meets all of these criteria. It is called minusconf . Turns off branching is not even necessary.

+3
source

When a node was found on the local network, I used Twisted and UDP multicast. I hope he helps you too.

Link to twisted documentation explaining how to do this: https://twistedmatrix.com/documents/current/core/howto/udp.html#auto3

Here is a basic twisted-code server / client implementation. It answers itself if you run once, but all the verification code and additional functions have been removed to make reading easier.

 from twisted.internet.protocol import DatagramProtocol from twisted.internet import reactor class MulticastPingPong(DatagramProtocol): MULTICAST_ADDR = ('228.0.0.5', 8005) CMD_PING = "PING" CMD_PONG = "PONG" def startProtocol(self): """ Called after protocol has started listening. """ # Set the TTL>1 so multicast will cross router hops: self.transport.setTTL(5) # Join a specific multicast group: self.transport.joinGroup(self.MULTICAST_ADDR[0]) self.send_alive() def send_alive(self): """ Sends a multicast signal asking for clients. The receivers will reply if they want to be found. """ self.transport.write(self.CMD_PING, self.MULTICAST_ADDR) def datagramReceived(self, datagram, address): print "Datagram %s received from %s" % (repr(datagram), repr(address)) if datagram.startswith(self.CMD_PING): # someone publishes itself, we reply that we are here self.transport.write(self.CMD_PONG, address) elif datagram.startswith(self.CMD_PONG): # someone reply to our publish message print "Got client: ", address[0], address[1] if __name__ == '__main__': reactor.listenMulticast(8005, MulticastPingPong(), listenMultiple=True) reactor.run() 
+2
source

I assume that you have control over the client applications, not just the server application, in which case Pyro might work well for you.

Flexible: uses unprivileged ports.

Continuous:. It has been well maintained for many years.

Portable: pure Python and well tested on several platforms.

Light: I think Pyro is light for what you get. Maybe a single Python script request is unrealistic for a network naming service?

Even if you don't want to use the Pyro "remote object" paradigm, you can still use your naming service.

+1
source

All Articles