|
- package bridge
-
- import (
- "fmt"
- "log/slog"
-
- "github.com/AFASystems/presence/internal/pkg/config"
- mqtt "github.com/eclipse/paho.mqtt.golang"
- "github.com/google/uuid"
- )
-
- const defaultMQTTPort = 1883
- const subscribeTopic = "publish_out/#"
- const disconnectQuiesceMs = 250
-
- // MQTTClient wraps paho MQTT client and options.
- type MQTTClient struct {
- Client mqtt.Client
- }
-
- // NewMQTTClient creates and connects an MQTT client. Returns error instead of panic on connect failure.
- func NewMQTTClient(cfg *config.Config, publishHandler func(mqtt.Message)) (*MQTTClient, error) {
- opts := mqtt.NewClientOptions()
- opts.AddBroker(fmt.Sprintf("tcp://%s:%d", cfg.MQTTHost, defaultMQTTPort))
- opts.SetClientID(fmt.Sprintf("bridge-%s", uuid.New().String()))
- opts.SetAutoReconnect(true)
- opts.SetConnectRetry(true)
- opts.SetConnectRetryInterval(config.SMALL_TICKER_INTERVAL)
- opts.SetMaxReconnectInterval(config.LARGE_TICKER_INTERVAL)
- opts.SetCleanSession(false)
- opts.SetDefaultPublishHandler(func(c mqtt.Client, m mqtt.Message) {
- publishHandler(m)
- })
- opts.OnConnect = func(client mqtt.Client) {
- slog.Info("MQTT connected")
- }
- opts.OnConnectionLost = func(client mqtt.Client, err error) {
- slog.Error("MQTT connection lost", "err", err)
- }
-
- client := mqtt.NewClient(opts)
- token := client.Connect()
- token.Wait()
- if err := token.Error(); err != nil {
- return nil, fmt.Errorf("mqtt connect: %w", err)
- }
- return &MQTTClient{Client: client}, nil
- }
-
- // Subscribe subscribes to the default bridge topic.
- func (m *MQTTClient) Subscribe() {
- token := m.Client.Subscribe(subscribeTopic, 1, nil)
- token.Wait()
- slog.Info("MQTT subscribed", "topic", subscribeTopic)
- }
-
- // Disconnect disconnects the client with quiesce.
- func (m *MQTTClient) Disconnect() {
- m.Client.Disconnect(disconnectQuiesceMs)
- slog.Info("MQTT disconnected")
- }
|