基于Golang和MQTT的物联网平台开发实践

基于Golang和MQTT的物联网平台开发实践 大家好,我刚刚完成了Go语言的在线课程学习,想要基于MQTT开发一个类似http://thingspeak.com的物联网平台。但我不知道该从何入手?我发现了一个用Go语言编写的MQTT服务器叫VolantMQ。是否需要下载并修改VolantMQ的源代码来实现我的目标?如果问题过于笼统还请见谅。如果能指导我该采取什么方法,我将不胜感激。如果还需要学习更多计算机科学相关课程,也希望能为我推荐。由于我是计算机科学领域的新手,不太清楚该如何以及在哪里使用GitHub上已有的代码,又该在何处编写自己的代码?


更多关于基于Golang和MQTT的物联网平台开发实践的实战教程也可以访问 https://www.itying.com/category-94-b0.html

9 回复

是否必须基于 MQTT?

更多关于基于Golang和MQTT的物联网平台开发实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是的,因为 MQTT 在低带宽数据传输方面具有出色的性能和特性。

你编写的插件几乎支持我需要的所有功能,你建议我在项目中使用你的插件吗?

感谢您花费时间进行解释,这确实很有启发性。

使用 paho mqtt Go 客户端,是否支持通过数据库对用户进行授权?为了过滤消息,我是否应该订阅代理接收的所有传入消息?

你可能不想折腾 MQTT 代理的内部机制,而且很可能也不需要这样做。相反,只需选择一个免费或开源的代理(我推荐 mosquitto),并使用某个 Go 客户端(例如,https://github.com/eclipse/paho.mqtt.golang)在你的应用程序中发布和订阅主题。

认证和授权由代理服务器负责。对于 Mosquitto 来说,它支持通过认证插件作为链接共享对象进行静态文件认证或自定义方法。虽然几个月前已归档,但最流行和使用最多的是 https://github.com/jpmens/mosquitto-auth-plug,它是用 C 语言编写的。还有 https://github.com/iegomez/mosquitto-go-auth,这是我用 Go 语言编写的,共享了许多功能,但在一些后端能力和其他细节上有所不同。既然你想练习 Go 语言,你可以编写自己的插件来处理你的认证需求。

据我所知,该组件已在多个生产项目中投入使用,因为它已被纳入LoRa Server官方文档体系(这也是我最初开发它的原因)。对于用户反馈的问题,我也会尽快响应处理。从这个角度来说,请放心使用。当然也要说明,其他同类解决方案也值得考虑。

无论如何,认证插件应当作为应用程序的辅助工具存在,并具备可替换性:真正重要且具有核心价值的是应用程序的主体业务逻辑,这才是需要重点构建的部分。

我认为readme文档已经清晰说明了插件的功能,但如果您遇到任何问题欢迎提交issue,若在开发过程中遇到困难也随时可以联系我。祝您开发顺利!

对于基于Golang和MQTT开发物联网平台,建议采用以下方法:

1. 核心架构设计

物联网平台通常包含设备接入、数据处理、存储和API服务等模块。建议采用分层架构:

  • MQTT Broker:负责设备连接和消息路由
  • 业务逻辑层:处理设备数据解析和业务规则
  • 数据存储层:持久化设备数据和元数据
  • REST API:提供外部访问接口

2. MQTT Broker选择

VolantMQ是一个完整的MQTT broker实现,但直接修改其源代码可能过于复杂。推荐以下两种方案:

方案A:使用现有MQTT Broker

// 使用Eclipse Paho的Go客户端连接现有MQTT Broker
import (
    "fmt"
    mqtt "github.com/eclipse/paho.mqtt.golang"
)

func connectMQTT() mqtt.Client {
    opts := mqtt.NewClientOptions()
    opts.AddBroker("tcp://localhost:1883")
    opts.SetClientID("iot-platform")
    
    client := mqtt.NewClient(opts)
    if token := client.Connect(); token.Wait() && token.Error() != nil {
        panic(token.Error())
    }
    return client
}

方案B:集成VolantMQ作为库

// 将VolantMQ作为库集成到你的应用中
import (
    "github.com/VolantMQ/volantmq"
    "github.com/VolantMQ/volantmq/config"
)

func startEmbeddedBroker() {
    cfg := config.Default()
    broker, err := volantmq.New(cfg)
    if err != nil {
        panic(err)
    }
    
    // 启动嵌入式MQTT broker
    if err := broker.Listen(); err != nil {
        panic(err)
    }
}

3. 设备数据接收和处理

// 订阅设备主题并处理数据
type DeviceData struct {
    DeviceID string  `json:"device_id"`
    Value    float64 `json:"value"`
    Timestamp int64  `json:"timestamp"`
}

func handleDeviceData(client mqtt.Client) {
    token := client.Subscribe("devices/+/data", 1, func(client mqtt.Client, msg mqtt.Message) {
        var data DeviceData
        if err := json.Unmarshal(msg.Payload(), &data); err != nil {
            log.Printf("Error parsing device data: %v", err)
            return
        }
        
        // 处理设备数据
        processDeviceData(data)
    })
    
    token.Wait()
}

func processDeviceData(data DeviceData) {
    // 数据验证、转换、存储等业务逻辑
    fmt.Printf("Received data from device %s: %f\n", data.DeviceID, data.Value)
    
    // 存储到数据库
    saveToDatabase(data)
}

4. REST API实现

// 使用Gin框架提供REST API
import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func setupAPI() *gin.Engine {
    r := gin.Default()
    
    // 设备数据查询接口
    r.GET("/devices/:id/data", func(c *gin.Context) {
        deviceID := c.Param("id")
        data := getDeviceData(deviceID)
        c.JSON(http.StatusOK, data)
    })
    
    // 设备注册接口
    r.POST("/devices", func(c *gin.Context) {
        var device struct {
            ID   string `json:"id"`
            Name string `json:"name"`
        }
        
        if err := c.BindJSON(&device); err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            return
        }
        
        registerDevice(device.ID, device.Name)
        c.JSON(http.StatusCreated, gin.H{"status": "registered"})
    })
    
    return r
}

5. 数据存储示例

// 使用SQLite或PostgreSQL存储设备数据
import (
    "database/sql"
    _ "github.com/mattn/go-sqlite3"
)

func initDatabase() *sql.DB {
    db, err := sql.Open("sqlite3", "./iotplatform.db")
    if err != nil {
        panic(err)
    }
    
    // 创建设备数据表
    _, err = db.Exec(`
        CREATE TABLE IF NOT EXISTS device_data (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            device_id TEXT NOT NULL,
            value REAL NOT NULL,
            timestamp INTEGER NOT NULL
        )
    `)
    
    if err != nil {
        panic(err)
    }
    
    return db
}

6. 主程序入口

func main() {
    // 初始化数据库
    db := initDatabase()
    defer db.Close()
    
    // 启动MQTT客户端
    mqttClient := connectMQTT()
    defer mqttClient.Disconnect(250)
    
    // 设置设备数据处理
    handleDeviceData(mqttClient)
    
    // 启动REST API服务器
    router := setupAPI()
    router.Run(":8080")
}

实施建议:

  1. 先从简单的MQTT客户端开始,理解消息收发机制
  2. 逐步添加数据存储和REST API功能
  3. 使用VolantMQ作为嵌入式broker或连接现有的MQTT服务器
  4. GitHub上的代码可以作为参考,但建议基于标准库和成熟框架构建自己的应用

这种方法可以让你专注于业务逻辑开发,而不是从头实现MQTT协议。随着项目进展,你可以根据需求逐步优化各个模块。

回到顶部