Files
mqtt_explorer/backend/internal/mqtt/manager.go
Gilles Soulier 383ad292d3 first
2025-12-24 14:47:39 +01:00

83 lines
2.1 KiB
Go

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)
}
}