0

I think it is a silly question, I need a MQTT Client to keep running after connection and subscription. I never encountered the problem because my MQTT clients are always coupled with an HTTP server, and when launching a HTTP server, the code don't stop running.

But in the present use case I only need a MQTT Client to subscribe to some topic and stay alive.

Here is what I do (the function just connect to a broker and subcribe to one topic.)

func main() {
    godotenv.Load("./.env")
    _initMqttConnection()
}

I need the client to stay connected and not stop just after the subscription is done.

How to perform that simple thing ?

Edit 1 : Complete Code

package main

import (
 "encoding/json"
 "fmt"
 "log"
 "net/http"
 "os"
 "path/filepath"
 "strings"

 "github.com/yosssi/gmq/mqtt"
 "github.com/yosssi/gmq/mqtt/client"

 "github.com/joho/godotenv"

 "github.com/skratchdot/open-golang/open"
)

var cli *client.Client

func _initMqttConnection() {
 cli = client.New(&client.Options{
  ErrorHandler: func(err error) {
   fmt.Println(err)
  },
 })
 defer cli.Terminate()
 log.Println("Connecting to " + os.Getenv("mqtt_host"))

 err := cli.Connect(&client.ConnectOptions{
  Network:  "tcp",
  Address:  os.Getenv("mqtt_host"),
  UserName: []byte(os.Getenv("mqtt_user")),
  Password: []byte(os.Getenv("mqtt_password")),
  ClientID: []byte("mqtt_video_launcher"),
 })
 if err != nil {
  log.Println("Error 1")
  panic(err)
 }
 log.Println("Connected to MQTT")

 topic_to_sub := []byte("/" + os.Getenv("video_topic"))

 err = cli.Subscribe(&client.SubscribeOptions{
  SubReqs: []*client.SubReq{
   &client.SubReq{
    TopicFilter: topic_to_sub,
    QoS:         mqtt.QoS0,
    Handler: func(topicName, message []byte) {
     //do struff with message
          fmt.Println(string(topicName), string(message))
    },
   },
  },
 })
 if err != nil {
  panic(err)
 }
 log.Println("Subscription OK : " + string(topic_to_sub[:len(topic_to_sub)]))
}

func main() {
 godotenv.Load("./.env")
 _initMqttConnection()
}

The temporary solution I use is adding :

http.ListenAndServe(":", nil)

at the end.

NeitoFR
  • 716
  • 1
  • 11
  • 23
  • 1
    Can you provide a minimal and complete code sample, including the import of the actual mqtt library you're using? – Eli Bendersky May 08 '19 at 12:21
  • 1
    You can check out the answer on this question https://stackoverflow.com/questions/48872360/golang-mqtt-publish-and-subscribe I think that would also help you. In essence, they've created a channel that waits for an input (`SIGTERM`). As long as that input doesn't come, the program won't stop and the connection will remain open. – retgits May 08 '19 at 15:37

1 Answers1

1

You have to make the program run infinitely or unless you want to explicitly end it (Cntrl c). One good solution that worked for me is to wait for a channel before exiting the main function and that channel can keep listening for an interrupt.

Eg:

func main() {

    keepAlive := make(chan os.Signal)
    signal.Notify(keepAlive, os.Interrupt, syscall.SIGTERM)

    // All your code

    <-keepAlive
}