### Create Paho.golang Router Source: https://github.com/eclipse-paho/paho.golang/blob/master/autopaho/examples/router/readme.md Initializes a new standard router for handling MQTT message routing. This router will be used to direct incoming messages to specific handlers based on their topic. ```go router := paho.NewStandardRouter() ``` -------------------------------- ### Register and Unregister Router Handlers Source: https://github.com/eclipse-paho/paho.golang/blob/master/autopaho/examples/router/readme.md Demonstrates how to add, remove, and define handlers for specific MQTT topics using the Paho.golang router. A default handler is also registered to catch messages not matching any specific topic patterns. ```go router.DefaultHandler(func(p *paho.Publish) { fmt.Printf("defaulthandler received message with topic: %s\n", p.Topic) }) router.RegisterHandler("test/test/#", func(p *paho.Publish) { fmt.Printf("test/test/# received message with topic: %s\n", p.Topic) }) router.UnregisterHandler("test/test/#") ``` -------------------------------- ### Subscribe to MQTT Topics with ConnectionManager in Go Source: https://context7.com/eclipse-paho/paho.golang/llms.txt Demonstrates how to subscribe to one or more MQTT topics with specified QoS levels using the ConnectionManager. Subscriptions are made within the OnConnectionUp callback to ensure they are re-established after reconnection. This example uses the 'github.com/eclipse/paho.golang/autopaho' and 'github.com/eclipse/paho.golang/paho' packages. ```go package main import ( "context" "fmt" "net/url" "github.com/eclipse/paho.golang/autopaho" "github.com/eclipse/paho.golang/paho" ) func main() { serverURL, _ := url.Parse("mqtt://localhost:1883") cliCfg := autopaho.ClientConfig{ ServerUrls: []*url.URL{serverURL}, KeepAlive: 30, OnConnectionUp: func(cm *autopaho.ConnectionManager, connAck *paho.Connack) { // Subscribe in OnConnectionUp to re-establish on reconnect suback, err := cm.Subscribe(context.Background(), &paho.Subscribe{ Subscriptions: []paho.SubscribeOptions{ {Topic: "sensors/+/temperature", QoS: 1}, // Single-level wildcard {Topic: "alerts/#", QoS: 2}, // Multi-level wildcard {Topic: "config/device-01", QoS: 0, NoLocal: true}, // Don't receive own messages }, }) if err != nil { fmt.Printf("Subscribe failed: %s\n", err) return } for i, reason := range suback.Reasons { fmt.Printf("Subscription %d: reason code %d\n", i, reason) } }, ClientConfig: paho.ClientConfig{ ClientID: "subscriber-client", OnPublishReceived: []func(paho.PublishReceived) (bool, error){ func(pr paho.PublishReceived) (bool, error) { fmt.Printf("Received on %s: %s\n", pr.Packet.Topic, pr.Packet.Payload) return true, nil }, }, }, } cm, _ := autopaho.NewConnection(context.Background(), cliCfg) cm.AwaitConnection(context.Background()) select {} } // Output: Subscription 0: reason code 1 // Output: Subscription 1: reason code 2 // Output: Subscription 2: reason code 0 // Output: Received on sensors/living-room/temperature: {"value": 22.5} ``` -------------------------------- ### Configure Client to Use Router Source: https://github.com/eclipse-paho/paho.golang/blob/master/autopaho/examples/router/readme.md Configures the AutoPaho client to use the router for handling received messages. The `OnPublishReceived` callback is set to invoke the router's `Route` method for each incoming message. ```go autopaho.ClientConfig{ OnPublishReceived: []func (paho.PublishReceived) (bool, error){ func (pr paho.PublishReceived) (bool, error) { router.Route(pr.Packet.Packet()) return true, nil // we assume that the router handles all messages (todo: amend router API) }}, } ``` -------------------------------- ### Create Managed MQTT Connection with AutoPaho Source: https://context7.com/eclipse-paho/paho.golang/llms.txt Demonstrates how to create a new managed MQTT connection using autopaho.ClientConfig. This setup automatically handles connection establishment, reconnection on failure, and session management, making it suitable for production IoT applications. It requires setting up server URLs, keep-alive intervals, and callback functions for connection events. ```go package main import ( "context" "fmt" "net/url" "os" "os/signal" "syscall" "github.com/eclipse/paho.golang/autopaho" "github.com/eclipse/paho.golang/paho" ) func main() { ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() serverURL, _ := url.Parse("mqtt://mqtt.eclipseprojects.io:1883") cliCfg := autopaho.ClientConfig{ ServerUrls: []*url.URL{serverURL}, KeepAlive: 20, CleanStartOnInitialConnection: false, SessionExpiryInterval: 60, // Session survives 60 seconds after disconnect OnConnectionUp: func(cm *autopaho.ConnectionManager, connAck *paho.Connack) { fmt.Println("Connection established") }, OnConnectError: func(err error) { fmt.Printf("Connection error: %s\n", err) }, ClientConfig: paho.ClientConfig{ ClientID: "my-unique-client-id", OnClientError: func(err error) { fmt.Printf("Client error: %s\n", err) }, }, } cm, err := autopaho.NewConnection(ctx, cliCfg) if err != nil { panic(err) } // Wait for connection to be established if err = cm.AwaitConnection(ctx); err != nil { panic(err) } fmt.Println("Connected successfully") <-ctx.Done() <-cm.Done() } // Output: Connection established // Output: Connected successfully ``` -------------------------------- ### Publish Messages Reliably with ConnectionManager Queue in Go Source: https://context7.com/eclipse-paho/paho.golang/llms.txt Demonstrates how to queue messages for reliable delivery using the ConnectionManager, even when the MQTT connection is down. Messages are stored in a persistent file-based queue and transmitted once the connection is re-established. This example utilizes 'github.com/eclipse/paho.golang/autopaho' and 'github.com/eclipse/paho.golang/autopaho/queue/file'. ```go package main import ( "context" "fmt" "net/url" "github.com/eclipse/paho.golang/autopaho" "github.com/eclipse/paho.golang/autopaho/queue/file" "github.com/eclipse/paho.golang/paho" ) func main() { serverURL, _ := url.Parse("mqtt://localhost:1883") // Use file-based queue for persistence across restarts fileQueue, err := file.New("./mqtt-queue", "msg", ".dat") if err != nil { panic(err) } cliCfg := autopaho.ClientConfig{ ServerUrls: []*url.URL{serverURL}, Queue: fileQueue, // Persistent queue KeepAlive: 30, SessionExpiryInterval: 3600, // 1 hour session persistence ClientConfig: paho.ClientConfig{ ClientID: "reliable-publisher", }, } cm, _ := autopaho.NewConnection(context.Background(), cliCfg) // Note: We don't wait for connection - messages queue immediately // Queue messages even if connection is down for i := 0; i < 10; i++ { err := cm.PublishViaQueue(context.Background(), &autopaho.QueuePublish{ Publish: &paho.Publish{ QoS: 1, Topic: "telemetry/data", Payload: []byte(fmt.Sprintf(`{"seq": %d, "data": "sample"}`, i)), }, }) if err != nil { fmt.Printf("Failed to queue message: %s\n", err) } } fmt.Println("Messages queued for delivery") // Messages will be delivered when connection comes up select {} } // Output: Messages queued for delivery ``` -------------------------------- ### Initialize and Run AutoPaho MQTT Client Source: https://github.com/eclipse-paho/paho.golang/blob/master/autopaho/readme.md Demonstrates how to configure and run an AutoPaho MQTT client, including setting up connection callbacks, handling subscriptions on connection, and publishing messages in a loop. ```go func main() { ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() u, err := url.Parse("mqtt://mqtt.eclipseprojects.io:1883") if err != nil { panic(err) } cliCfg := autopaho.ClientConfig{ ServerUrls: []*url.URL{u}, KeepAlive: 20, CleanStartOnInitialConnection: false, SessionExpiryInterval: 60, OnConnectionUp: func(cm *autopaho.ConnectionManager, connAck *paho.Connack) { fmt.Println("mqtt connection up") if _, err := cm.Subscribe(context.Background(), &paho.Subscribe{ Subscriptions: []paho.SubscribeOptions{ {Topic: topic, QoS: 1}, }, }); err != nil { fmt.Printf("failed to subscribe (%s). This is likely to mean no messages will be received.", err) } fmt.Println("mqtt subscription made") }, OnConnectError: func(err error) { fmt.Printf("error whilst attempting connection: %s\n", err) }, ClientConfig: paho.ClientConfig{ ClientID: clientID, OnPublishReceived: []func(paho.PublishReceived) (bool, error){ func(pr paho.PublishReceived) (bool, error) { fmt.Printf("received message on topic %s; body: %s (retain: %t)\n", pr.Packet.Topic, pr.Packet.Payload, pr.Packet.Retain) return true, nil }}, OnClientError: func(err error) { fmt.Printf("client error: %s\n", err) }, OnServerDisconnect: func(d *paho.Disconnect) { if d.Properties != nil { fmt.Printf("server requested disconnect: %s\n", d.Properties.ReasonString) } else { fmt.Printf("server requested disconnect; reason code: %d\n", d.ReasonCode) } }, }, } c, err := autopaho.NewConnection(ctx, cliCfg) if err != nil { panic(err) } if err = c.AwaitConnection(ctx); err != nil { panic(err) } ticker := time.NewTicker(time.Second) msgCount := 0 defer ticker.Stop() for { select { case <-ticker.C: msgCount++ if _, err = c.Publish(ctx, &paho.Publish{ QoS: 1, Topic: topic, Payload: []byte("TestMessage: " + strconv.Itoa(msgCount)), }); err != nil { if ctx.Err() == nil { panic(err) } } continue case <-ctx.Done(): } break } fmt.Println("signal caught - exiting") <-c.Done() } ``` -------------------------------- ### Establish WebSocket MQTT Connection in Go Source: https://context7.com/eclipse-paho/paho.golang/llms.txt Demonstrates connecting to an MQTT broker over WebSockets, which is ideal for browser-based clients or environments requiring HTTP proxy traversal. Includes custom header configuration for authentication. ```go package main import ( "context" "crypto/tls" "fmt" "net/http" "net/url" "github.com/eclipse/paho.golang/autopaho" "github.com/eclipse/paho.golang/paho" ) func main() { serverURL, _ := url.Parse("wss://mqtt.example.com:443/mqtt") cliCfg := autopaho.ClientConfig{ ServerUrls: []*url.URL{serverURL}, TlsCfg: &tls.Config{ MinVersion: tls.VersionTLS12, }, WebSocketCfg: &autopaho.WebSocketConfig{ Header: func(u *url.URL, tlsCfg *tls.Config) http.Header { h := http.Header{} h.Add("Authorization", "Bearer your-token-here") return h }, }, KeepAlive: 30, OnConnectionUp: func(cm *autopaho.ConnectionManager, connAck *paho.Connack) { fmt.Println("WebSocket connection established") }, ClientConfig: paho.ClientConfig{ ClientID: "websocket-client", }, } cm, _ := autopaho.NewConnection(context.Background(), cliCfg) cm.AwaitConnection(context.Background()) } ``` -------------------------------- ### Publish MQTT Messages with Different QoS Levels Source: https://context7.com/eclipse-paho/paho.golang/llms.txt Illustrates how to publish messages to an MQTT broker using the ConnectionManager's Publish method with varying Quality of Service (QoS) levels (0, 1, and 2). This function demonstrates fire-and-forget (QoS 0), at-least-once delivery (QoS 1) with retain option, and exactly-once delivery (QoS 2) with advanced properties like content type and user properties. It requires an active ConnectionManager instance and returns an error if the publish operation fails. ```go package main import ( "context" "fmt" "net/url" "time" "github.com/eclipse/paho.golang/autopaho" "github.com/eclipse/paho.golang/paho" ) func publishMessage(cm *autopaho.ConnectionManager) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // QoS 0: Fire and forget _, err := cm.Publish(ctx, &paho.Publish{ QoS: 0, Topic: "sensors/temperature", Payload: []byte(`{"value": 23.5, "unit": "celsius"}`), }) if err != nil { return fmt.Errorf("QoS 0 publish failed: %w", err) } // QoS 1: At least once delivery resp, err := cm.Publish(ctx, &paho.Publish{ QoS: 1, Topic: "sensors/humidity", Payload: []byte(`{"value": 65, "unit": "percent"}`), Retain: true, // Message will be retained by broker }) if err != nil { return fmt.Errorf("QoS 1 publish failed: %w", err) } fmt.Printf("Published with packet ID: %d\n", resp.PacketID) // QoS 2: Exactly once delivery with properties _, err = cm.Publish(ctx, &paho.Publish{ QoS: 2, Topic: "alerts/critical", Payload: []byte(`{"alert": "high_temperature", "severity": "critical"}`), Properties: &paho.PublishProperties{ ContentType: "application/json", MessageExpiry: paho.Uint32(3600), // Expires in 1 hour User: paho.UserProperties{ {Key: "source", Value: "sensor-01"}, }, }, }) return err } // Output: Published with packet ID: 1 ``` -------------------------------- ### Manage Low-Level MQTT Connections Source: https://context7.com/eclipse-paho/paho.golang/llms.txt Provides a manual approach to MQTT client management using paho.Client. This requires explicit TCP connection handling, manual subscription, and publishing, offering maximum control over the MQTT session. ```go package main import ( "context" "fmt" "net" "time" "github.com/eclipse/paho.golang/paho" ) func main() { // Establish TCP connection manually conn, err := net.Dial("tcp", "mqtt.eclipseprojects.io:1883") if err != nil { panic(err) } // Create client with connection client := paho.NewClient(paho.ClientConfig{ Conn: conn, ClientID: "low-level-client", OnPublishReceived: []func(paho.PublishReceived) (bool, error){ func(pr paho.PublishReceived) (bool, error) { fmt.Printf("Received: %s\n", pr.Packet.Payload) return true, nil }, }, OnClientError: func(err error) { fmt.Printf("Client error: %s\n", err) }, }) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // Connect to broker connAck, err := client.Connect(ctx, &paho.Connect{ KeepAlive: 30, ClientID: "low-level-client", CleanStart: true, Properties: &paho.ConnectProperties{ SessionExpiryInterval: paho.Uint32(3600), }, }) if err != nil { panic(err) } fmt.Printf("Connected: session present=%t\n", connAck.SessionPresent) // Subscribe _, err = client.Subscribe(ctx, &paho.Subscribe{ Subscriptions: []paho.SubscribeOptions{ {Topic: "test/topic", QoS: 1}, }, }) if err != nil { panic(err) } // Publish _, err = client.Publish(ctx, &paho.Publish{ Topic: "test/topic", QoS: 1, Payload: []byte("Hello from low-level client"), }) if err != nil { panic(err) } time.Sleep(2 * time.Second) // Disconnect client.Disconnect(&paho.Disconnect{ReasonCode: 0}) <-client.Done() } ``` -------------------------------- ### Implement RPC Messaging with MQTT Source: https://context7.com/eclipse-paho/paho.golang/llms.txt Demonstrates request/response patterns over MQTT using the paho.golang RPC extension. It includes both the client-side request logic and the server-side response handling using correlation data and response topics. ```go package main import ( "context" "fmt" "time" "github.com/eclipse/paho.golang/paho" "github.com/eclipse/paho.golang/paho/extensions/rpc" ) // Client side: Making RPC requests func makeRPCRequest(client *paho.Client) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // Create RPC handler (subscribes to response topic automatically) handler, err := rpc.NewHandler(ctx, client) if err != nil { panic(err) } // Send request and wait for response response, err := handler.Request(ctx, &paho.Publish{ Topic: "services/calculator/add", QoS: 1, Payload: []byte(`{"a": 5, "b": 3}`), }) if err != nil { fmt.Printf("RPC error: %s\n", err) return } fmt.Printf("RPC response: %s\n", response.Payload) } // Server side: Handling RPC requests func handleRPCRequests(client *paho.Client) { client.AddOnPublishReceived(func(pr paho.PublishReceived) (bool, error) { if pr.Packet.Topic != "services/calculator/add" { return false, nil } // Process request result := `{"result": 8}` // Send response using ResponseTopic and CorrelationData from request if pr.Packet.Properties != nil && pr.Packet.Properties.ResponseTopic != "" { _, err := client.Publish(context.Background(), &paho.Publish{ Topic: pr.Packet.Properties.ResponseTopic, QoS: 1, Payload: []byte(result), Properties: &paho.PublishProperties{ CorrelationData: pr.Packet.Properties.CorrelationData, }, }) if err != nil { return true, err } } return true, nil }) } ``` -------------------------------- ### Establish TLS/SSL MQTT Connection in Go Source: https://context7.com/eclipse-paho/paho.golang/llms.txt Configures a secure MQTT connection using TLS, supporting custom CA certificates and mutual TLS authentication. It utilizes the autopaho package to manage the connection lifecycle with specific TLS configurations. ```go package main import ( "context" "crypto/tls" "crypto/x509" "fmt" "net/url" "os" "github.com/eclipse/paho.golang/autopaho" "github.com/eclipse/paho.golang/paho" ) func main() { caCert, err := os.ReadFile("ca.crt") if err != nil { panic(err) } caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(caCert) clientCert, err := tls.LoadX509KeyPair("client.crt", "client.key") if err != nil { panic(err) } tlsConfig := &tls.Config{ RootCAs: caCertPool, Certificates: []tls.Certificate{clientCert}, MinVersion: tls.VersionTLS12, } serverURL, _ := url.Parse("tls://mqtt.example.com:8883") cliCfg := autopaho.ClientConfig{ ServerUrls: []*url.URL{serverURL}, TlsCfg: tlsConfig, KeepAlive: 30, OnConnectionUp: func(cm *autopaho.ConnectionManager, connAck *paho.Connack) { fmt.Println("Secure connection established") }, ClientConfig: paho.ClientConfig{ ClientID: "secure-client", }, } cm, _ := autopaho.NewConnection(context.Background(), cliCfg) cm.AwaitConnection(context.Background()) fmt.Println("Connected with TLS") } ``` -------------------------------- ### Manual Message Acknowledgment in Go Source: https://context7.com/eclipse-paho/paho.golang/llms.txt Demonstrates how to enable manual control over QoS 1/2 message acknowledgments in the Paho Go client. This is useful for scenarios where message processing verification is required before acknowledging receipt to the broker. It requires setting `EnableManualAcknowledgment` to true and implementing the `OnPublishReceived` callback to handle acknowledgments. ```go package main import ( "context" "fmt" "net/url" "time" "github.com/eclipse/paho.golang/autopaho" "github.com/eclipse/paho.golang/paho" ) func main() { serverURL, _ := url.Parse("mqtt://localhost:1883") cliCfg := autopaho.ClientConfig{ ServerUrls: []*url.URL{serverURL}, KeepAlive: 30, OnConnectionUp: func(cm *autopaho.ConnectionManager, connAck *paho.Connack) { cm.Subscribe(context.Background(), &paho.Subscribe{ Subscriptions: []paho.SubscribeOptions{ {Topic: "important/messages", QoS: 2}, }, }) }, ClientConfig: paho.ClientConfig{ ClientID: "manual-ack-client", EnableManualAcknowledgment: true, SendAcksInterval: 100 * time.Millisecond, OnPublishReceived: []func(paho.PublishReceived) (bool, error){ func(pr paho.PublishReceived) (bool, error) { fmt.Printf("Processing message: %s\n", pr.Packet.Payload) // Simulate processing time.Sleep(100 * time.Millisecond) // Process the message... success := processMessage(pr.Packet.Payload) if success { // Acknowledge only after successful processing if err := pr.Client.Ack(pr.Packet); err != nil { fmt.Printf("Ack error: %s\n", err) } fmt.Println("Message acknowledged") } else { fmt.Println("Processing failed, not acknowledging") // Message will be redelivered by broker } return true, nil }, }, }, } cm, _ := autopaho.NewConnection(context.Background(), cliCfg) cm.AwaitConnection(context.Background()) select {} } func processMessage(payload []byte) bool { // Your processing logic here return true } ``` -------------------------------- ### Route MQTT Messages with StandardRouter Source: https://context7.com/eclipse-paho/paho.golang/llms.txt Implements a message router that dispatches incoming PUBLISH messages to handlers based on topic patterns. It supports MQTT wildcards (+ and #) and allows for default handlers for unmatched topics. ```go func main() { router := paho.NewStandardRouter() router.RegisterHandler("sensors/temperature", func(p *paho.Publish) { fmt.Printf("Temperature: %s\n", p.Payload) }) router.RegisterHandler("sensors/+/humidity", func(p *paho.Publish) { fmt.Printf("Humidity from %s: %s\n", p.Topic, p.Payload) }) router.RegisterHandler("alerts/#", func(p *paho.Publish) { fmt.Printf("Alert: %s - %s\n", p.Topic, p.Payload) }) router.DefaultHandler(func(p *paho.Publish) { fmt.Printf("Unhandled message on %s\n", p.Topic) }) router.UnregisterHandler("sensors/temperature") } ``` -------------------------------- ### Configure Last Will and Testament (LWT) in Go Source: https://context7.com/eclipse-paho/paho.golang/llms.txt Sets up a 'Last Will' message that the broker publishes if the client disconnects unexpectedly. Includes configuration for will delay intervals, content type, and message expiry properties. ```go package main import ( "context" "fmt" "net/url" "github.com/eclipse/paho.golang/autopaho" "github.com/eclipse/paho.golang/paho" ) func main() { serverURL, _ := url.Parse("mqtt://localhost:1883") willDelayInterval := uint32(10) cliCfg := autopaho.ClientConfig{ ServerUrls: []*url.URL{serverURL}, KeepAlive: 30, WillMessage: &paho.WillMessage{ Topic: "clients/device-01/status", Payload: []byte(`{"status": "offline", "reason": "unexpected_disconnect"}`), QoS: 1, Retain: true, }, WillProperties: &paho.WillProperties{ WillDelayInterval: &willDelayInterval, ContentType: "application/json", MessageExpiry: paho.Uint32(86400), }, OnConnectionUp: func(cm *autopaho.ConnectionManager, connAck *paho.Connack) { cm.Publish(context.Background(), &paho.Publish{ Topic: "clients/device-01/status", QoS: 1, Retain: true, Payload: []byte(`{"status": "online"}`), }) fmt.Println("Published online status") }, ClientConfig: paho.ClientConfig{ ClientID: "device-01", }, } cm, _ := autopaho.NewConnection(context.Background(), cliCfg) cm.AwaitConnection(context.Background()) select {} } ``` -------------------------------- ### Unsubscribe from MQTT Topics using ConnectionManager Source: https://context7.com/eclipse-paho/paho.golang/llms.txt Removes subscriptions from the broker using the ConnectionManager. It returns an Unsuback containing reason codes for each request, allowing for validation of successful unsubscriptions. ```go func unsubscribeFromTopics(cm *autopaho.ConnectionManager, topics []string) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() unsuback, err := cm.Unsubscribe(ctx, &paho.Unsubscribe{ Topics: topics, }) if err != nil { return fmt.Errorf("unsubscribe failed: %w", err) } for i, reason := range unsuback.Reasons { if reason >= 0x80 { fmt.Printf("Failed to unsubscribe from %s: reason code %d\n", topics[i], reason) } else { fmt.Printf("Unsubscribed from %s\n", topics[i]) } } return nil } ``` -------------------------------- ### Custom Reconnection Backoff in Go Source: https://context7.com/eclipse-paho/paho.golang/llms.txt Illustrates how to configure custom reconnection backoff strategies for the Paho Go MQTT client. This allows for flexible retry mechanisms, such as exponential backoff with jitter, to handle network interruptions gracefully. The `ReconnectBackoff` field in `autopaho.ClientConfig` accepts a function that determines the delay between reconnection attempts. ```go package main import ( "context" "fmt" "math" "net/url" "time" "github.com/eclipse/paho.golang/autopaho" "github.com/eclipse/paho.golang/paho" ) func main() { serverURL, _ := url.Parse("mqtt://localhost:1883") // Exponential backoff with jitter exponentialBackoff := func(attempt int) time.Duration { base := float64(time.Second) max := float64(2 * time.Minute) backoff := base * math.Pow(2, float64(attempt-1)) if backoff > max { backoff = max } return time.Duration(backoff) } cliCfg := autopaho.ClientConfig{ ServerUrls: []*url.URL{serverURL}, KeepAlive: 30, ReconnectBackoff: exponentialBackoff, ConnectTimeout: 10 * time.Second, OnConnectError: func(err error) { fmt.Printf("Connection failed: %s (will retry)\n", err) }, OnConnectionUp: func(cm *autopaho.ConnectionManager, connAck *paho.Connack) { fmt.Println("Connected!") }, OnConnectionDown: func() bool { fmt.Println("Connection lost, will attempt reconnect") return true // Return false to stop reconnection attempts }, ClientConfig: paho.ClientConfig{ ClientID: "backoff-client", }, } // Built-in constant backoff helper _ = autopaho.NewConstantBackoff(5 * time.Second) cm, _ := autopaho.NewConnection(context.Background(), cliCfg) cm.AwaitConnection(context.Background()) select {} } ``` -------------------------------- ### Perform Graceful Disconnection with ConnectionManager Source: https://context7.com/eclipse-paho/paho.golang/llms.txt Gracefully disconnects from the MQTT broker by sending a DISCONNECT packet and waiting for a clean shutdown. This ensures all pending operations are finalized before the connection closes. ```go func gracefulShutdown(cm *autopaho.ConnectionManager) error { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() fmt.Println("Initiating graceful disconnect...") if err := cm.Disconnect(ctx); err != nil { return fmt.Errorf("disconnect error: %w", err) } fmt.Println("Disconnected successfully") return nil } func waitForShutdown(cm *autopaho.ConnectionManager) { <-cm.Done() fmt.Println("Connection manager has shutdown") } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.