package main import ( "fmt" "log" "time" mqtt "github.com/eclipse/paho.mqtt.golang" ) const ( QOS = byte(1) RETAINED = true MQTT_CONNECT_TIMEOUT = 1 * time.Second MQTT_DISCONNECT_TIMEOUT_US = 500 MQTT_KEEPALIVE_PERIOD = 2 * time.Second ) var ( mqttServerHealthTopic string ) type MQTTMessage struct { Topic string Payload []byte } func MQTTRun(config MQTTConfig, tx chan MQTTMessage) { mqttServerHealthTopic = fmt.Sprintf("%s/server/health", config.TopicPrefix) opts := mqtt.NewClientOptions() opts.AddBroker(config.Broker) opts.SetClientID(config.ClientID) opts.SetCleanSession(true) opts.SetOnConnectHandler(MQTTOnConnectHandler) opts.SetConnectionLostHandler(MQTTConnectionLostHandler) opts.SetAutoReconnect(true) opts.SetConnectRetry(true) opts.SetConnectTimeout(MQTT_CONNECT_TIMEOUT) opts.SetKeepAlive(MQTT_KEEPALIVE_PERIOD) opts.SetWill(mqttServerHealthTopic, `bad`, QOS, true) client := mqtt.NewClient(opts) token := client.Connect() success := token.WaitTimeout(MQTT_CONNECT_TIMEOUT) if !success { log.Fatal("Initial connection to MQTT broker failed.") } defer client.Disconnect(MQTT_DISCONNECT_TIMEOUT_US) for message := range tx { topic := fmt.Sprintf("%s/%s", config.TopicPrefix, message.Topic) client.Publish(topic, QOS, RETAINED, message.Payload) } } func MQTTOnConnectHandler(c mqtt.Client) { log.Printf("Connected to MQTT broker.") c.Publish(mqttServerHealthTopic, QOS, true, []byte(`good`)) } func MQTTConnectionLostHandler(c mqtt.Client, err error) { log.Printf("Connection to MQTT broker lost: %v", err) }