package main import ( "context" "fmt" "log" "net/url" "os" "os/signal" "syscall" "time" "github.com/eclipse/paho.golang/autopaho" "github.com/eclipse/paho.golang/paho" ) func main() { if err := run(); err != nil { log.Fatal(err) } } func run() error { ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() user := os.Getenv("TEST_MQTT5_MQTT_USERNAME") pass := os.Getenv("TEST_MQTT5_MQTT_PASSWORD") if user == "" || pass == "" { return fmt.Errorf("TEST_MQTT5_MQTT_USERNAME and TEST_MQTT5_MQTT_PASSWORD environment variables not set") } broker, err := url.Parse("mqtt://127.0.0.1:18883") if err != nil { return fmt.Errorf("failed to parse broker url: %w", err) } cfg := autopaho.ClientConfig{ ServerUrls: []*url.URL{broker}, KeepAlive: 20, CleanStartOnInitialConnection: true, SessionExpiryInterval: 0, ConnectUsername: user, ConnectPassword: []byte(pass), OnConnectionUp: func(_ *autopaho.ConnectionManager, ack *paho.Connack) { log.Printf("connected: session_present=%t reason=0x%02x", ack.SessionPresent, ack.ReasonCode) }, OnConnectionDown: func() bool { log.Print("connection down; AutoPaho will retry") return true }, OnConnectError: func(err error) { log.Printf("connect attempt failed: %v", err) }, ClientID: "lab-backend", OnClientError: func(err error) { log.Printf("client error: %v", err) }, OnServerDisconnect: func(packet *paho.Disconnect) { log.Printf("server disconnected: reason=0x%02x", packet.ReasonCode) }, } manager, err := autopaho.NewConnection(ctx, cfg) if err != nil { return fmt.Errorf("failed to create connection manager: %w", err) } defer func() { shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := manager.Disconnect(shutdownCtx); err != nil { log.Printf("shutdown did not finish within deadline: %v", err) } }() startup, cancel := context.WithTimeout(ctx, 10*time.Second) err = manager.AwaitConnection(startup) cancel() if err != nil { return fmt.Errorf("failed to connect to broker: %w", err) } log.Print("connected to broker; pres Ctrl+C to stop") <-ctx.Done() return nil }