Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

golang mqtt publish and subscribe

Does anybody know where I can get some example MQTT client Go (golang) code that does both publish and subscribe in an infinite loop ?

I am messaging with a Mosquitto broker running on MacOs.

In more detail...

  1. Get a message from the network (a topic)
  2. Compute something based on that message
  3. Send the result of the computation back to the network (topic)

Here is the code I am using:

package main

import (
"fmt"
 MQTT "github.com/eclipse/paho.mqtt.golang"
"os"
"time"
)

var knt int

var f MQTT.MessageHandler = func(client MQTT.Client, msg MQTT.Message) 
{ 
   fmt.Printf("MSG: %s\n", msg.Payload())
   text:= fmt.Sprintf("this is result msg #%d!", knt)
   knt++
   token := client.Publish("nn/result", 0, false, text)
   token.Wait()
}

func main() {
   knt = 0

   opts := MQTT.NewClientOptions().AddBroker("tcp://localhost:1883")
   opts.SetClientID("mac-go")
   opts.SetDefaultPublishHandler(f)

   c := MQTT.NewClient(opts)
   if token := c.Connect(); token.Wait() && token.Error() != nil {
        panic(token.Error())
   }

  if token := c.Subscribe("nn/sensors", 0, nil); token.Wait() && 
     token.Error() != nil {
     fmt.Println(token.Error())
     os.Exit(1)
  }

  time.Sleep(3 * time.Second)
} //end of main

I looked through the GoDocs for some hint as to how to keep the connections open but nothing seems pertinent. I can certainly do an infinite loop over the 'subscribe' but that seems inefficient.

like image 438
Phillip Neal Avatar asked Feb 19 '18 18:02

Phillip Neal


People also ask

Is MQTT a publish subscribe protocol?

MQTT is a topic-based pub/sub protocol that uses char- acter strings to provide support of hierarchical topics. This also facilitates the subscription to multiple topics.

Is MQTT based on publish subscribe architecture?

MQTT is the standard protocol for messaging and data exchange for the Internet of Things. The protocol uses a publish/subscribe architecture. The technology provides a scalable and cost-effective way to connect devices over the Internet.

Can we subscribe publish to multiple topics in MQTT?

Can MQTT subscribe to multiple topics? Yes. You can use MQTT wildcards to subscribe to multiple topics simultaneously. A wildcard can only be used to subscribe to topics, not to publish a message.


1 Answers

I looked through the GoDocs for some hint as to how to keep the connections open but nothing seems pertinent. I can certainly do an infinite loop over the 'subscribe' but that seems inefficient.

Ok. Found a solution at . https://github.com/eclipse/paho.mqtt.golang/blob/master/cmd/stdoutsub/main.go. Essentially, I had to open up a channel for the subscribe. Here is the new code:

package main

import (
    "fmt"
    MQTT "github.com/eclipse/paho.mqtt.golang"
    "os"
    "os/signal"
    "syscall"
)

var knt int
var f MQTT.MessageHandler = func(client MQTT.Client, msg MQTT.Message) {
    fmt.Printf("MSG: %s\n", msg.Payload())
    text := fmt.Sprintf("this is result msg #%d!", knt)
    knt++
    token := client.Publish("nn/result", 0, false, text)
    token.Wait()
}

func main() {
    knt = 0
    c := make(chan os.Signal, 1)
    signal.Notify(c, os.Interrupt, syscall.SIGTERM)

    opts := MQTT.NewClientOptions().AddBroker("tcp://localhost:1883")
    opts.SetClientID("mac-go")
    opts.SetDefaultPublishHandler(f)
    topic := "nn/sensors"

    opts.OnConnect = func(c MQTT.Client) {
            if token := c.Subscribe(topic, 0, f); token.Wait() && token.Error() != nil {
                    panic(token.Error())
            }
    }
    client := MQTT.NewClient(opts)
    if token := client.Connect(); token.Wait() && token.Error() != nil {
            panic(token.Error())
    } else {
            fmt.Printf("Connected to server\n")
    }
    <-c
}
like image 170
Phillip Neal Avatar answered Oct 02 '22 14:10

Phillip Neal