go操作mqtt

795 阅读3分钟

简介

在 Go 语言中,连接到 MQTT 服务并监听特定主题(topic)的消息通常涉及以下步骤:

  1. 选择 MQTT 客户端库:Go 语言有多个 MQTT 客户端库可供选择。常用的一个是 eclipse/paho.mqtt.golang。(是mqtt-go star最高的项目)
  2. 安装 MQTT 客户端库:使用 go get 命令安装所选的 MQTT 客户端库。例如,安装 eclipse/paho.mqtt.golang:

go get github.com/eclipse/paho.mqtt.golang

  1. 编写代码以连接 MQTT 服务器:创建 MQTT 客户端,配置连接参数,并连接到 MQTT 服务器。
  2. 订阅主题并设置消息处理回调:订阅你感兴趣的主题,并定义一个回调函数来处理接收到的消息。
  3. 处理接收到的消息:在回调函数中实现你对接收到的消息的处理逻辑。
  4. 断开连接:在适当的时候断开与 MQTT 服务器的连接。

以下是一个简单的示例,展示了如何使用 eclipse/paho.mqtt.golang 库连接 MQTT 服务并监听特定主题:

package main

import (
    "fmt"
    MQTT "github.com/eclipse/paho.mqtt.golang"
    "os"
    "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 = "tcp://localhost:1883"
    var topic = "testtopic/#"

    opts := MQTT.NewClientOptions()
    opts.AddBroker(broker)
    opts.SetClientID("go_mqtt_client")
    opts.SetUsername("yourusername")
    opts.SetPassword("yourpassword")
    opts.SetDefaultPublishHandler(messagePubHandler)
    opts.OnConnect = connectHandler
    opts.OnConnectionLost = connectLostHandler

    client := MQTT.NewClient(opts)
    if token := client.Connect(); token.Wait() && token.Error() != nil {
        fmt.Println(token.Error())
        os.Exit(1)
    }

    client.Subscribe(topic, 1, nil)
    time.Sleep(60 * time.Second) // 等待接收消息

    client.Disconnect(250)
}

如果要发布一条消息

	// 发布消息
	message := "hello mqtt"
	token := client.Publish(topic, 0, false, message)
	token.Wait()

在这个示例中:

  • 使用 eclipse/paho.mqtt.golang 库创建了一个 MQTT 客户端。
  • 配置了客户端的连接参数,包括服务器地址、客户端 ID、用户名和密码。
  • 设置了消息处理函数 messagePubHandler,它会在接收到消息时被调用。
  • 连接到 MQTT 服务器,并订阅了指定的主题。
  • 等待一段时间接收消息,然后断开连接。

确保将 broker、topic、yourusername 和 yourpassword 替换为实际的 MQTT 服务器信息和你的认证信息。此外,根据你的需求调整消息处理逻辑和订阅的主题。

token.Wait()/Error()

在 eclipse/paho.mqtt.golang 这个 MQTT 客户端库中,token.Wait() 和 token.Error() 是与异步操作相关的方法,用于处理 MQTT 操作的结果。这两个方法通常与发送消息(Publish)和订阅主题(Subscribe)等异步 MQTT 操作一起使用。下面详细解释这两个方法的作用和原理:

token.Wait()

  • token.Wait() 是一个阻塞调用,用于等待 MQTT 操作(如发送消息或订阅主题)的完成。
  • 当你调用一个如 Publish 或 Subscribe 的方法时,这些方法立即返回一个 Token 对象,并且相关的 MQTT 操作在后台异步执行。
  • 调用 token.Wait() 将阻塞当前线程,直到相关的 MQTT 操作完成(成功或失败)。
  • 这种方式允许程序继续执行其他任务,而不是立即等待 MQTT 操作的响应。

token.Error()

  • token.Error() 方法返回在 MQTT 操作过程中遇到的任何错误。
  • 如果操作成功完成,token.Error() 将返回 nil。
  • 如果操作失败,比如网络问题或其他原因导致无法发送消息或订阅主题,token.Error() 将返回一个描述错误的 error 对象。
  • 通常在调用 token.Wait() 后检查 token.Error(),以确定操作是否成功。

示例使用

在 MQTT 客户端的典型使用场景中,你会看到这样的代码模式:

token := client.Publish(topic, qos, retained, payload)
token.Wait()
if err := token.Error(); err != nil {
    // 处理错误
    fmt.Println("Error publishing message:", err)
}

在这个示例中:

  • client.Publish(...) 发送一个消息,并立即返回一个 Token。
  • token.Wait() 阻塞等待发布操作完成。
  • token.Error() 检查是否有任何错误发生,如果有,就处理这个错误。

使用 token.Wait() 和 token.Error() 的模式确保了代码在进行下一步之前正确地等待并处理了 MQTT 操作的结果。这对于维护程序的稳定性和健壮性是非常重要的。