Golang与MQTT:轻松构建物联网应用
在今天的数字时代,物联网和实时消息传递变得越来越重要。Golang,由Google推出的革命性编程语言,与MQTT,一个高效的物联网消息传输协议,共同为开发者带来了无数的机会。这篇文章将带你走进Golang和MQTT的世界,详细介绍如何实现二者的融合与应用。
1. 为什么选择Golang?
Golang以其简洁、强大和高效的特性而脱颖而出,特别适合处理并发任务,是物联网项目的理想选择。
2. MQTT: 物联网的动力
MQTT的发布/订阅模式使其成为物联网领域的翘楚。它能够为联网设备提供实时、可靠的消息服务,广泛应用于各个行业。
3. 开启Golang与MQTT的旅程
我们将使用paho.mqtt.golang
库,这是一个为Golang设计的高效MQTT客户端。
3.1 项目准备
确保你的系统安装了go1.13.12
或更高版本。安装paho.mqtt.golang
:
go get github.com/eclipse/paho.mqtt.golang
3.2 连接到MQTT broker
我们选择EMQX提供的公共MQTT服务器,地址为broker.emqx.io
。
package main
import (
"fmt"
mqtt "github.com/eclipse/paho.mqtt.golang"
"time"
)
var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
fmt.Printf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic())
}
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 = "broker.emqx.io"
var port = 1883
opts := mqtt.NewClientOptions()
opts.AddBroker(fmt.Sprintf("tcp://%s:%d", broker, port))
opts.SetClientID("go_mqtt_client")
opts.SetUsername("emqx")
opts.SetPassword("public")
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())
}
}
- ClientOptions:用于设置 broker,端口,客户端 id ,用户名密码等选项
- messagePubHandler:全局 MQTT pub 消息处理
- connectHandler:连接的回调
- connectLostHandler:连接丢失的回调
如果想使用 TLS 连接,可以如下设置:
func NewTlsConfig() *tls.Config {
certpool := x509.NewCertPool()
ca, err := ioutil.ReadFile("ca.pem")
if err != nil {
log.Fatalln(err.Error())
}
certpool.AppendCertsFromPEM(ca)
// Import client certificate/key pair
clientKeyPair, err := tls.LoadX509KeyPair("client-crt.pem", "client-key.pem")
if err != nil {
panic(err)
}
return &tls.Config{
RootCAs: certpool,
ClientAuth: tls.NoClientCert,
ClientCAs: nil,
InsecureSkipVerify: true,
Certificates: []tls.Certificate{clientKeyPair},
}
}
如果不设置客户端证书,可以如下设置:
func NewTlsConfig() *tls.Config {
certpool := x509.NewCertPool()
ca, err := ioutil.ReadFile("ca.pem")
if err != nil {
log.Fatalln(err.Error())
}
certpool.AppendCertsFromPEM(ca)
return &tls.Config{
RootCAs: certpool,
}
}
然后设置 TLS
var broker = "broker.emqx.io"
var port = 8883
opts := mqtt.NewClientOptions()
opts.AddBroker(fmt.Sprintf("ssl://%s:%d", broker, port))
tlsConfig := NewTlsConfig()
opts.SetTLSConfig(tlsConfig)
// other options
3.3 MQTT消息发布与订阅
Golang与MQTT的结合使得消息发布和订阅变得轻而易举。
订阅
func sub(client mqtt.Client) {
topic := "topic/test"
token := client.Subscribe(topic, 1, nil)
token.Wait()
fmt.Printf("Subscribed to topic %s", topic)
}
发布
func publish(client mqtt.Client) {
num := 10
for i := 0; i < num; i++ {
text := fmt.Sprintf("Message %d", i)
token := client.Publish("topic/test", 0, false, text)
token.Wait()
time.Sleep(time.Second)
}
}
4. 深入理解:连接回调与安全性
当与broker的连接建立或断开时,执行相应的回调函数可以增加程序的健壮性。同时,为了数据安全,建议使用TLS连接。
5. 实战测试
通过以下代码,我们可以一目了然地了解如何在Golang中实现MQTT客户端的完整流程。
package main
import (
"fmt"
mqtt "github.com/eclipse/paho.mqtt.golang"
"log"
"time"
)
var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
fmt.Printf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic())
}
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 = "broker.emqx.io"
var port = 1883
opts := mqtt.NewClientOptions()
opts.AddBroker(fmt.Sprintf("tcp://%s:%d", broker, port))
opts.SetClientID("go_mqtt_client")
opts.SetUsername("emqx")
opts.SetPassword("public")
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) {
num := 10
for i := 0; i < num; i++ {
text := fmt.Sprintf("Message %d", i)
token := client.Publish("topic/test", 0, false, text)
token.Wait()
time.Sleep(time.Second)
}
}
func sub(client mqtt.Client) {
topic := "topic/test"
token := client.Subscribe(topic, 1, nil)
token.Wait()
fmt.Printf("Subscribed to topic: %s", topic)
}
运行代码,可以看到 MQTT 连接、订阅成功,并能成功收到订阅 topic 的消息
6. 结语
结合Golang的强大性能和MQTT的轻量级特点,为物联网应用开发提供了一个强大的解决方案。通过这篇文章,您应该已经掌握了如何使用Golang构建MQTT应用的基本知识,期待您在实际应用中创造更多的可能性。
本文旨在为读者提供真实、有价值的内容,如有任何建议或反馈,请随时与我们联系。
您必须登录才能发表评论。