fix(mdns-scanner): browser par type au lieu d'une recherche globale
bonjour-service exige un `type` dans BrowserConfig ; il n'existe pas d'option pour écouter "tous les services". Le scanner instancie maintenant un browser par type mDNS courant en homelab (http, ssh, smb, airplay, googlecast, homekit, ipp, etc.) et agrège les annonces par IP via une fonction `ingest` partagée. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,36 @@
|
||||
import { Bonjour } from 'bonjour-service';
|
||||
import { Bonjour, type Service } from 'bonjour-service';
|
||||
import { env } from '@/config/env';
|
||||
import type { DiscoveryResult, DiscoveryTarget, Scanner } from '../types';
|
||||
|
||||
/**
|
||||
* Découverte via mDNS / DNS-SD (_services._dns-sd._udp.local).
|
||||
* Écoute pendant `timeout` ms et agrège les annonces reçues.
|
||||
* Découverte via mDNS / DNS-SD.
|
||||
* `bonjour-service` exige un `type` par browser : on en lance un par type
|
||||
* courant en homelab et on agrège les annonces reçues pendant `timeout` ms.
|
||||
*/
|
||||
const DEFAULT_TIMEOUT_MS = 4000;
|
||||
|
||||
// Types mDNS les plus fréquents en homelab (sans le préfixe `_` ni le suffixe `._tcp/._udp`)
|
||||
const COMMON_SERVICE_TYPES: Array<{ type: string; protocol: 'tcp' | 'udp' }> = [
|
||||
{ type: 'http', protocol: 'tcp' },
|
||||
{ type: 'https', protocol: 'tcp' },
|
||||
{ type: 'ssh', protocol: 'tcp' },
|
||||
{ type: 'sftp-ssh', protocol: 'tcp' },
|
||||
{ type: 'smb', protocol: 'tcp' },
|
||||
{ type: 'nfs', protocol: 'tcp' },
|
||||
{ type: 'afpovertcp', protocol: 'tcp' },
|
||||
{ type: 'workstation', protocol: 'tcp' },
|
||||
{ type: 'device-info', protocol: 'tcp' },
|
||||
{ type: 'printer', protocol: 'tcp' },
|
||||
{ type: 'ipp', protocol: 'tcp' },
|
||||
{ type: 'ipps', protocol: 'tcp' },
|
||||
{ type: 'airplay', protocol: 'tcp' },
|
||||
{ type: 'raop', protocol: 'tcp' },
|
||||
{ type: 'googlecast', protocol: 'tcp' },
|
||||
{ type: 'homekit', protocol: 'tcp' },
|
||||
{ type: 'hap', protocol: 'tcp' },
|
||||
{ type: 'spotify-connect', protocol: 'tcp' },
|
||||
];
|
||||
|
||||
export const mdnsScanner: Scanner = {
|
||||
kind: 'mdns',
|
||||
label: 'mDNS / Bonjour',
|
||||
@@ -17,11 +40,14 @@ export const mdnsScanner: Scanner = {
|
||||
const bonjour = new Bonjour();
|
||||
const byIp = new Map<string, DiscoveryResult>();
|
||||
|
||||
const browser = bonjour.find({});
|
||||
browser.on('up', (svc) => {
|
||||
const ingest = (svc: Service) => {
|
||||
const ips = (svc.addresses ?? []).filter((a) => a && !a.includes(':')); // IPv4
|
||||
for (const ip of ips) {
|
||||
const existing = byIp.get(ip) ?? { ipAddress: ip, hostname: svc.host, services: [] };
|
||||
const existing = byIp.get(ip) ?? {
|
||||
ipAddress: ip,
|
||||
hostname: svc.host,
|
||||
services: [],
|
||||
};
|
||||
existing.services!.push({
|
||||
name: svc.name,
|
||||
type: `_${svc.type}._${svc.protocol}.local`,
|
||||
@@ -29,10 +55,16 @@ export const mdnsScanner: Scanner = {
|
||||
});
|
||||
byIp.set(ip, existing);
|
||||
}
|
||||
};
|
||||
|
||||
const browsers = COMMON_SERVICE_TYPES.map(({ type, protocol }) => {
|
||||
const browser = bonjour.find({ type, protocol });
|
||||
browser.on('up', ingest);
|
||||
return browser;
|
||||
});
|
||||
|
||||
await new Promise((r) => setTimeout(r, DEFAULT_TIMEOUT_MS));
|
||||
browser.stop();
|
||||
for (const b of browsers) b.stop();
|
||||
bonjour.destroy();
|
||||
|
||||
return [...byIp.values()];
|
||||
|
||||
Reference in New Issue
Block a user