01 · Problem
Wofür braucht man das?
Geräte im selben LAN sollen Dienste finden, ohne einen zentralen DNS-Server oder fest konfigurierte IP-Adressen zu benötigen.
02 · Denkmodell
Das mentale Modell
mDNS ist eine gemeinschaftliche Multicast-Zone. Queries werden nicht wie RPCs korreliert, sondern Antworten für Name und Typ innerhalb eines kurzen Fensters gesammelt.
MDNS registriert lokale Records und versucht Queries über eine erfundene TXT-Query-ID zuzuordnen. Die Antwort echo't diese ID nicht; Abhängigkeit und NodeNext-Imports sind fehlerhaft, sodass das Package nicht baut.
03 · Kontrollfluss
Was passiert in welcher Reihenfolge?
- UDP-Multicast-Socket für Port 5353 öffnen und Response-Listener zuerst registrieren.
- Standardkonforme Frage mit Name und Typ senden.
- Passende Answer- und Additional-Records während eines Sammelfensters erfassen.
- Records normalisieren und deduplizieren, danach Listener und Timer entfernen.
- Beim Shutdown alle ausstehenden Queries abbrechen und Socket schließen.
04 · Bauteile
Die entscheidenden Verträge
MDNS.query(name, type)
Soll einen passenden DNSRecord als Promise auflösen.
MDNS.announce(name, type, ttl, data)
Registriert im Repository einen Record, sendet aber keine proaktive Announcement-Response.
destroy()
Entfernt Listener und zerstört die multicast-dns-Instanz.
DNSRecord / DNSType
Typen für A, AAAA, PTR, TXT und SRV ohne vollständig gekoppelte Payloads.
05 · Build it yourself
Selbst implementieren
Verwende das normale DNS-Protokoll und korreliere über Name, Typ und Zeitfenster statt über proprietäre Request-IDs.
- Modelliere Record-Typ und Payload als diskriminierte Union.
- Registriere Listener vor dem Senden und sammle mehrere Antworten bis zum Timeout.
- Bereinige Listener, Timeout und Pending-Promise bei Erfolg, Fehler, Abort und Shutdown.
async function query(name: string, type: string, signal: AbortSignal) {
const answers: unknown[] = [];
const onResponse = (packet: any) => {
for (const record of [...packet.answers, ...packet.additionals]) {
if (record.name === name && (type === "ANY" || record.type === type)) {
answers.push(record);
}
}
};
socket.on("response", onResponse);
try { socket.query({ questions: [{ name, type }] }); await delay(500, signal); }
finally { socket.off("response", onResponse); }
return deduplicate(answers);
}06 · Verifizieren
Was du testen solltest
- Mehrere Antworten, Duplikate und fremde Name/Typ-Kombinationen werden korrekt behandelt.
- Timeout, Abort und destroy entfernen Listener und settle'n jedes Promise genau einmal.
- PTR, SRV, TXT, A und AAAA behalten jeweils die richtige Datenform.
07 · Grenzen
Kompromisse und Stolperfallen
- mDNS funktioniert nur innerhalb einer Multicast-Domain und ist kein Internet-Service-Discovery.
- Antworten sind untrusted; Service-Metadaten beweisen keine Identität.
- Betriebssysteme und Netzwerke können Multicast filtern oder bündeln.
Ein mDNS-Query ist keine 1:1-RPC-Anfrage. Mehrere Geräte dürfen gleichzeitig und verzögert antworten.
08 · Weiterdenken