func (p *MQTTPublisher) discoverBrokerEndpoint() error { endpoint, err := catalog.DiscoverCatalogEndpoint(service.DNSSDServiceType) if err != nil { return err } rcc := service.NewRemoteCatalogClient(endpoint) res, _, err := rcc.FindServices("meta.serviceType", "equals", DNSSDServiceTypeMQTT, 1, 50) if err != nil { return err } supportsPub := false for _, s := range res { for _, proto := range s.Protocols { for _, m := range proto.Methods { if m == "PUB" { supportsPub = true break } } if !supportsPub { continue } logger.Println(proto.Endpoint["url"]) if ProtocolType(proto.Type) == ProtocolTypeMQTT { p.config.URL = proto.Endpoint["url"].(string) break } } } err = p.config.Validate() if err != nil { return err } return nil }
// Registers service in the remote catalog // endpoint: catalog endpoint. If empty - will be discovered using DNS-SD // s: service registration // sigCh: channel for shutdown signalisation from upstream func RegisterServiceWithKeepalive(endpoint string, discover bool, s Service, sigCh <-chan bool, wg *sync.WaitGroup) { defer wg.Done() var err error if discover { endpoint, err = utils.DiscoverCatalogEndpoint(DNSSDServiceType) if err != nil { logger.Printf("RegisterServiceWithKeepalive() ERROR: Failed to discover the endpoint: %v", err.Error()) return } } // Configure client client := NewRemoteCatalogClient(endpoint) // Will not keepalive registration with a negative TTL if s.Ttl <= 0 { logger.Println("RegisterServiceWithKeepalive() WARNING: Registration has ttl <= 0. Will not start the keepalive routine") RegisterService(client, &s) return } logger.Printf("RegisterServiceWithKeepalive() Will register and update registration periodically: %v/%v", endpoint, s.Id) // Configure & start the keepalive routine ksigCh := make(chan bool) kerrCh := make(chan error) go keepAlive(client, &s, ksigCh, kerrCh) for { select { // catch an error from the keepAlive routine case e := <-kerrCh: logger.Println("RegisterServiceWithKeepalive() ERROR:", e) // Re-discover the endpoint if needed and start over if discover { endpoint, err = utils.DiscoverCatalogEndpoint(DNSSDServiceType) if err != nil { logger.Println("RegisterServiceWithKeepalive() ERROR:", err.Error()) return } } logger.Println("RegisterServiceWithKeepalive() Will use the new endpoint: ", endpoint) client := NewRemoteCatalogClient(endpoint) go keepAlive(client, &s, ksigCh, kerrCh) // catch a shutdown signal from the upstream case <-sigCh: logger.Printf("RegisterServiceWithKeepalive() Removing the registration %v/%v...", endpoint, s.Id) // signal shutdown to the keepAlive routine & close channels select { case ksigCh <- true: // delete entry in the remote catalog client.Delete(s.Id) case <-time.After(1 * time.Second): logger.Printf("RegisterDeviceWithKeepalive(): timeout removing registration %v/%v: catalog unreachable", endpoint, s.Id) } close(ksigCh) close(kerrCh) return } } }