Go - MQTT Hello World
Go Paho MQTT Client
I already wrote a Go MQTT client before. I will try to expand this a little bit:
go mod init go/go-mqtt
go get github.com/eclipse/paho.mqtt.golang@latest
Connect to the MQTT broker
- Broker IP:
192.168.2.115
- MQTT Service Port:
1883
- Broker Login:
admin/instar
./main.go
package main
import (
"fmt"
"time"
mqtt "github.com/eclipse/paho.mqtt.golang"
)
var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
fmt.Printf("Topic: %s | %s\n", msg.Topic(), msg.Payload())
}
var connectHandler mqtt.OnConnectHandler = func(client mqtt.Client) {
fmt.Println("Connected")
}
var connectLostHandler mqtt.ConnectionLostHandler = func(client mqtt.Client, err error) {
fmt.Printf("Connect lost: %+v", err)
}
func main() {
var broker = "192.168.2.115"
var port = 1883
opts := mqtt.NewClientOptions()
opts.AddBroker(fmt.Sprintf("tcp://%s:%d", broker, port))
opts.SetClientID("go_mqtt_client")
opts.SetUsername("admin")
opts.SetPassword("instar")
opts.SetDefaultPublishHandler(messagePubHandler)
opts.OnConnect = connectHandler
opts.OnConnectionLost = connectLostHandler
client := mqtt.NewClient(opts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
panic(token.Error())
}
sub(client)
publish(client)
client.Disconnect(250)
}
func publish(client mqtt.Client) {
// Turn privacy mask 1 on and off again after 15s
nums := []int{1, 0}
for _, num := range nums {
value := fmt.Sprintf("%d", num)
token := client.Publish("cameras/115/multimedia/privacy/region1/enable/raw", 0, false, value)
token.Wait()
time.Sleep(15 * time.Second)
}
}
func sub(client mqtt.Client) {
// Subscribe to the LWT connection status
topic := "cameras/115/status/testament"
token := client.Subscribe(topic, 1, nil)
token.Wait()
fmt.Println("Subscribed to LWT", topic)
}
Running the Program
go run .\main.go
Connected
Subscribed to LWT cameras/115/status/testament
Topic: cameras/115/status/testament | {"val":"alive"}
The program connects to my camera broker, subscribes to the last-will topic and publishes updates to the privacy mask to turn it on and off again after 15s. The client disconnects after 250ms after that.
To get a binary file out I can run the build command:
go build ./main.go -o mqtt
And run the binary with ./mqtt
.
Cross Compiling with Go
Go supports a variety of platforms and operating systems, including:
- Android
- Darwin
- Linux
- Windows
The file created requires a 64bit x86-64
system to be executed:
file main
main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=GkWKfp1sGIj5CJ0LesYM/P1txXPn8ar3YIQEGRF3P/hbjIOYuyC5-d1UMZN32q/CGL0UrtrAC1goylMkfFl, with debug_info, not stripped
So how do I get a file that I can use on my IP camera that uses an ARM7 processor?
uname -m
armv7l
So how do I find out what systems are supported?
go tool dist list
android/386
android/amd64
android/arm
android/arm64
ios/amd64
ios/arm64
js/wasm
linux/386
linux/amd64
linux/arm
linux/arm64
linux/loong64
linux/mips
linux/mips64
linux/mips64le
linux/mipsle
linux/ppc64
linux/ppc64le
linux/riscv64
linux/s390x
windows/386
windows/amd64
windows/arm
windows/arm64
...
I can add the information as a environment variable when running the build:
env GOOS=linux GOARCH=arm go build -o mqtt_arm
Now I got a binary that can be executed on a 32bit ARM system:
file mqtt_arm
mqtt_arm: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, Go BuildID=msMp-jFIWHH3UaYAwNkh/TSOtDFvNMz_m1j_2VuU-/jOS7whdSr12-3_dBf4qC/xOLKo5WJnx4cluesUzqW, with debug_info, not stripped
And this worked - just copying the binary onto my IP Camera and executing it and I got the broker connection. Very nice <3