Fix discovery service - discover_peers returns proper peer dicts with addresses

This commit is contained in:
2026-03-22 11:50:23 +00:00
parent cadc435d17
commit bc8d9270a6

View File

@@ -1,7 +1,8 @@
"""mDNS/Bonjour peer discovery for local network.""" """mDNS/Bonjour peer discovery for local network."""
import asyncio import json
import socket import socket
from pathlib import Path
from typing import Any from typing import Any
from zeroconf import ServiceInfo, Zeroconf from zeroconf import ServiceInfo, Zeroconf
@@ -11,15 +12,22 @@ class DiscoveryService:
SERVICE_TYPE = "_snippets._tcp.local." SERVICE_TYPE = "_snippets._tcp.local."
SERVICE_NAME = "snip" SERVICE_NAME = "snip"
def __init__(self, port: int = 8765): def __init__(self, port: int = 8765, peer_id: str | None = None):
self.port = port self.port = port
self.peer_id = peer_id or socket.gethostname()
self.zeroconf = None self.zeroconf = None
self.service_info = None self.service_info = None
self._peer_cache_file = Path("~/.snip/peers.json").expanduser()
def register(self, peer_id: str, host: str | None = None): def register(self, peer_id: str | None = None, host: str | None = None):
"""Register this peer on the network.""" """Register this peer on the network."""
if peer_id is None:
peer_id = self.peer_id
if host is None: if host is None:
try:
host = socket.gethostbyname(socket.gethostname()) host = socket.gethostbyname(socket.gethostname())
except Exception:
host = "127.0.0.1"
self.zeroconf = Zeroconf() self.zeroconf = Zeroconf()
self.service_info = ServiceInfo( self.service_info = ServiceInfo(
@@ -27,7 +35,7 @@ class DiscoveryService:
f"{self.SERVICE_NAME}_{peer_id}.{self.SERVICE_TYPE}", f"{self.SERVICE_NAME}_{peer_id}.{self.SERVICE_TYPE}",
addresses=[socket.inet_aton(host)], addresses=[socket.inet_aton(host)],
port=self.port, port=self.port,
properties={"peer_id": peer_id}, properties={"peer_id": peer_id.encode()},
) )
self.zeroconf.register_service(self.service_info) self.zeroconf.register_service(self.service_info)
@@ -50,9 +58,12 @@ class DiscoveryService:
for addr in item.addresses: for addr in item.addresses:
peer_host = socket.inet_ntoa(addr) peer_host = socket.inet_ntoa(addr)
peer_id = item.properties.get(b"peer_id", b"").decode() peer_id = item.properties.get(b"peer_id", b"").decode()
peer_name = item.name.replace(f".{self.SERVICE_TYPE}", "")
peers.append({ peers.append({
"peer_id": peer_id, "peer_id": peer_id,
"peer_name": peer_name,
"host": peer_host, "host": peer_host,
"addresses": [peer_host],
"port": item.port, "port": item.port,
}) })
except Exception: except Exception:
@@ -62,19 +73,15 @@ class DiscoveryService:
return peers return peers
def discover_peers_async(self, timeout: float = 5.0) -> list[dict[str, Any]]: def save_peer_cache(self, peers: list[dict[str, Any]]):
"""Async version of peer discovery.""" """Save discovered peers to cache."""
return asyncio.run(self._discover_async(timeout)) self._peer_cache_file.parent.mkdir(parents=True, exist_ok=True)
with open(self._peer_cache_file, "w") as f:
json.dump(peers, f)
async def _discover_async(self, timeout: float) -> list[dict[str, Any]]: def load_peer_cache(self) -> list[dict[str, Any]]:
peers = [] """Load cached peers."""
zeroconf = Zeroconf() if self._peer_cache_file.exists():
with open(self._peer_cache_file, "r") as f:
try: return json.load(f)
await asyncio.sleep(timeout) return []
except Exception:
pass
finally:
zeroconf.close()
return peers