I am looking for a way for clients in a LAN to find all the instances of my server application without any configuration. Instead of hacking something myself, I'd like to use an existing solution. Personally, I need it to be done in Python, but I'd 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 couple of additional criteria, and I'm under the impression neither of the aforementioned systems matches them.
I'm looking for a solution that is:
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)
For node discovery in a LAN I've used Twisted and UDP Multicast. Hope it helps you too.
Link to the twisted documentation that explains how to do it: https://twistedmatrix.com/documents/current/core/howto/udp.html#auto3
Here is a basic implementation of a server/client based in the twisted's code. It answers itself if you run once, but all the checking code and extra features were removed in order to make it simpler to read.
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()
I wrote an application/library (currently Python and CLI interface) that matches all these critera. It's called minusconf. Turns out forking is not even necessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With