title: Flexible, Solid and Portable Service Discovery
body: <p>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.</p>
  <p>So why am I not using <a href="http://avahi.org/" rel="nofollow noreferrer">avahi</a> or <a href="http://www.openslp.org/" rel="nofollow noreferrer">OpenSLP</a> or some other <a href="http://en.wikipedia.org/wiki/Zeroconf#Service_discovery" rel="nofollow noreferrer">Zeroconf</a>/<a href="https://www.rfc-editor.org/rfc/rfc2608" rel="nofollow noreferrer">SLP</a> solution? Well, there are a couple of additional criteria, and I'm under the impression neither of the aforementioned systems matches them.</p>
  <p>I'm looking for a solution that is:</p>
  <ul>
  <li><strong>Flexible</strong>. It must not require superuser rights, i.e. only use ports&gt;1024.</li>
  <li><strong>Solid</strong>. It must allow multiple services of the same and different service type on a single machine and continue advertising the services even when the instance that started the advertisement server stops or crashes.</li>
  <li><strong>Portable</strong>. It must run nearly everywhere, or at least on *BSD, Debian/gentoo/RedHat/SuSe Linux, Mac OS X, Solaris and Windows NT.</li>
  <li><strong>Light</strong>. Ideally, one Python script would be the whole solution. I'm not in the least interested in address autoconfiguration or something like that, although I'd begrudgingly accept a solution that has lots of features I don't need. Furthermore, any one-time setup is a strict no-no.</li>
  </ul>
  <p>I expect something like this:</p>
  <pre><code>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 == &quot;localhost&quot;:
                      services.append(q.service)
      else:
          advertiseAt(&quot;localhost&quot;, service)
  </code></pre>