import logging import socket from zeroconf import Zeroconf, ServiceInfo, ServiceBrowser, ServiceStateChange logger = logging.getLogger() class ZeroconfServer(): def __init__(self, service_type, server_name, server_port): self.service_type = service_type self.server_name = server_name self.server_port = server_port self.server_ip = None self.zeroconf = Zeroconf() self.service_info = None self.client_cache = {} self.properties = {} def start(self, listen_only=False): if not listen_only: self._register_service() self._browse_services() def stop(self): self._unregister_service() self.zeroconf.close() def _register_service(self): self.server_ip = socket.gethostbyname(socket.gethostname()) info = ServiceInfo( self.service_type, f"{self.server_name}.{self.service_type}", addresses=[socket.inet_aton(self.server_ip)], port=self.server_port, properties=self.properties, ) self.service_info = info self.zeroconf.register_service(info) def _unregister_service(self): if self.service_info: self.zeroconf.unregister_service(self.service_info) self.service_info = None def _browse_services(self): browser = ServiceBrowser(self.zeroconf, self.service_type, [self._on_service_discovered]) def _on_service_discovered(self, zeroconf, service_type, name, state_change): info = zeroconf.get_service_info(service_type, name) logger.debug(f"Zeroconf: {name} {state_change}") if service_type == self.service_type: if state_change == ServiceStateChange.Added or state_change == ServiceStateChange.Updated: self.client_cache[name] = info else: self.client_cache.pop(name) def found_clients(self): return [x.split(f'.{self.service_type}')[0] for x in self.client_cache.keys()] # Example usage: if __name__ == "__main__": server = ZeroconfServer("_zordon._tcp.local.", "foobar.local", 8080) try: server.start() input("Server running - Press enter to end") finally: server.stop()