protected virtual void CheckKeepalive(IPAddress ip, ServiceEntry svc) { if (KeepalivePing) { Ping ping = new Ping(); var result = ping.Send(ip, (int)KeepaliveTimeout * 1000); if (result.Status != IPStatus.Success) { Debug.WriteLine("Removed service {0} at {1} due to keepalive ping failure", svc.Service, svc.Host); RemoveService(svc); return; } } if (KeepaliveTcp) { using (var sock = new KeepaliveSocket(ip, svc.Port)) { bool tcpConnected = sock.CanConnect((int)KeepaliveTimeout * 1000); if (!tcpConnected) { Debug.WriteLine("Removed service {0} at {1}:{2} due to Tcp Connect failure", svc.Service, svc.Host, svc.Port); RemoveService(svc); return; } } } // Service is alive svc.LastSeenAlive = DateTime.Now; HostUpdated?.Invoke(this, svc); }
public virtual void Init() { if (_disposedValue) { throw new ObjectDisposedException("ServiceDirectory"); } _mdns.NetworkInterfaceDiscovered += (s, e) => { // Ask for the name of all services. _sd.QueryAllServices(); }; _sd.ServiceDiscovered += (s, serviceName) => { // Check if this is a service we're interested in bool interesting = true; if (FilterFunction != null) { interesting = FilterFunction(serviceName.ToString()); } if (!interesting) { return; } // Ask for the name of instances of the service. _mdns.SendQuery(serviceName, type: DnsType.PTR); }; _sd.ServiceInstanceDiscovered += (s, e) => { // Ask for the service instance details. _mdns.SendQuery(e.ServiceInstanceName, type: DnsType.SRV); }; _sd.ServiceInstanceShutdown += (s, e) => { Debug.WriteLine("Removing service instance {0} from MDNS message", e.ServiceInstanceName); RemoveServiceByName(e.ServiceInstanceName.ToString()); }; _mdns.AnswerReceived += (s, e) => { // Is this an answer to a service instance details? var servers = e.Message.Answers.OfType <SRVRecord>(); foreach (var server in servers) { // For some reason, some services slip through the cracks of the first filter at ServiceDiscovered // and we have to filter again. bool interesting = true; if (FilterFunction != null) { interesting = FilterFunction(server.Name.ToString()); } if (!interesting) { continue; } var newSvc = new ServiceEntry { Host = server.Target.ToString(), Port = server.Port, Service = server.Name.ToString() }; AddService(newSvc); // Query IP addresses (only IPv4) _mdns.SendQuery(server.Target, type: DnsType.A); } // Is this an answer to host addresses? var addresses = e.Message.Answers.OfType <AddressRecord>(); foreach (var address in addresses) { // Find corresponding host lock (_entries) { var host = from entry in _entries where entry.Host == address.Name select entry; foreach (var h in host) { if (!h.IPAddresses.Contains(address.Address)) { h.IPAddresses.Add(address.Address); } HostUpdated?.Invoke(this, h); } } } }; _mdns.Start(); ScheduleKeepAliveCheck(); }