package mqtt import ( "fmt" "time" paho "github.com/eclipse/paho.mqtt.golang" ) type MessageHandler func(topic string, payload []byte, qos byte, retained bool) type Manager struct { client paho.Client handler MessageHandler subTopic string subQOS byte sysTopic string } func NewManager(broker, username, password, clientID string, handler MessageHandler, subTopic string, subQOS byte, sysTopic string) (*Manager, error) { opts := paho.NewClientOptions() opts.AddBroker(broker) opts.SetClientID(clientID) opts.SetAutoReconnect(true) opts.SetConnectRetry(true) opts.SetConnectRetryInterval(5 * time.Second) if username != "" { opts.SetUsername(username) opts.SetPassword(password) } mgr := &Manager{ handler: handler, subTopic: subTopic, subQOS: subQOS, sysTopic: sysTopic, } opts.SetOnConnectHandler(func(c paho.Client) { if token := c.Subscribe(mgr.subTopic, mgr.subQOS, mgr.onMessage); token.Wait() && token.Error() != nil { fmt.Printf("erreur subscribe MQTT: %v\n", token.Error()) } if mgr.sysTopic != "" { if token := c.Subscribe(mgr.sysTopic, mgr.subQOS, mgr.onMessage); token.Wait() && token.Error() != nil { fmt.Printf("erreur subscribe SYS MQTT: %v\n", token.Error()) } } }) opts.SetConnectionLostHandler(func(_ paho.Client, err error) { fmt.Printf("connexion MQTT perdue: %v\n", err) }) mgr.client = paho.NewClient(opts) if token := mgr.client.Connect(); token.Wait() && token.Error() != nil { return nil, fmt.Errorf("connexion MQTT: %w", token.Error()) } return mgr, nil } func (m *Manager) onMessage(_ paho.Client, msg paho.Message) { if m.handler == nil { return } m.handler(msg.Topic(), msg.Payload(), msg.Qos(), msg.Retained()) } func (m *Manager) Publish(topic string, payload []byte, qos byte, retained bool) error { if m.client == nil { return fmt.Errorf("client MQTT indisponible") } token := m.client.Publish(topic, qos, retained, payload) token.Wait() return token.Error() } func (m *Manager) Disconnect() { if m.client != nil && m.client.IsConnected() { m.client.Disconnect(250) } }