mirror of
https://github.com/varun-r-mallya/py-libp2p.git
synced 2025-12-31 20:36:24 +00:00
92 lines
2.9 KiB
Python
92 lines
2.9 KiB
Python
import logging
|
|
import socket
|
|
|
|
from zeroconf import (
|
|
EventLoopBlocked,
|
|
ServiceInfo,
|
|
Zeroconf,
|
|
)
|
|
|
|
logger = logging.getLogger("libp2p.discovery.mdns.broadcaster")
|
|
|
|
|
|
class PeerBroadcaster:
|
|
"""
|
|
Broadcasts this peer's presence on the local network using mDNS/zeroconf.
|
|
Registers a service with the peer's ID in the TXT record as per libp2p spec.
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
zeroconf: Zeroconf,
|
|
service_type: str,
|
|
service_name: str,
|
|
peer_id: str,
|
|
port: int,
|
|
):
|
|
self.zeroconf = zeroconf
|
|
self.service_type = service_type
|
|
self.peer_id = peer_id
|
|
self.port = port
|
|
self.service_name = service_name
|
|
|
|
# Get the local IP address
|
|
local_ip = self._get_local_ip()
|
|
hostname = socket.gethostname()
|
|
|
|
self.service_info = ServiceInfo(
|
|
type_=self.service_type,
|
|
name=self.service_name,
|
|
port=self.port,
|
|
properties={b"id": self.peer_id.encode()},
|
|
server=f"{hostname}.local.",
|
|
addresses=[socket.inet_aton(local_ip)],
|
|
)
|
|
|
|
def _get_local_ip(self) -> str:
|
|
"""Get the local IP address of this machine"""
|
|
try:
|
|
# Connect to a remote address to determine the local IP
|
|
# This doesn't actually send data
|
|
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
|
|
s.connect(("8.8.8.8", 80))
|
|
local_ip = s.getsockname()[0]
|
|
return local_ip
|
|
except Exception:
|
|
# Fallback to localhost if we can't determine the IP
|
|
return "127.0.0.1"
|
|
|
|
def register(self) -> None:
|
|
"""Register the peer's mDNS service on the network."""
|
|
try:
|
|
self.zeroconf.register_service(self.service_info)
|
|
logger.debug(f"mDNS service registered: {self.service_name}")
|
|
except EventLoopBlocked as e:
|
|
logger.warning(
|
|
"EventLoopBlocked while registering mDNS '%s': %s", self.service_name, e
|
|
)
|
|
except Exception as e:
|
|
logger.error(
|
|
"Unexpected error during mDNS registration for '%s': %r",
|
|
self.service_name,
|
|
e,
|
|
)
|
|
|
|
def unregister(self) -> None:
|
|
"""Unregister the peer's mDNS service from the network."""
|
|
try:
|
|
self.zeroconf.unregister_service(self.service_info)
|
|
logger.debug(f"mDNS service unregistered: {self.service_name}")
|
|
except EventLoopBlocked as e:
|
|
logger.warning(
|
|
"EventLoopBlocked while unregistering mDNS '%s': %s",
|
|
self.service_name,
|
|
e,
|
|
)
|
|
except Exception as e:
|
|
logger.error(
|
|
"Unexpected error during mDNS unregistration for '%s': %r",
|
|
self.service_name,
|
|
e,
|
|
)
|