插件窝 干货文章 EMQX、Go-Gin设备通信:认证、指令发送及业务处理如何实现?

EMQX、Go-Gin设备通信:认证、指令发送及业务处理如何实现?

设备 指令 Gin device 404    来源:    2025-03-11

在物联网(IoT)系统中,EMQX 是一个高性能的 MQTT 消息代理,而 Go-Gin 是一个基于 Go 语言的高性能 Web 框架。结合 EMQX 和 Go-Gin 可以实现设备的认证、指令发送及业务处理。以下是实现这些功能的步骤和思路:

1. 设备认证

设备认证是确保只有合法的设备可以连接到 EMQX 的关键步骤。EMQX 支持多种认证方式,包括用户名/密码认证、JWT 认证、客户端证书认证等。

1.1 用户名/密码认证

  • EMQX 配置:在 EMQX 中配置用户名和密码认证插件(如 emqx_auth_username)。
  • Go-Gin 实现
    • 提供一个 API 接口,用于设备注册或获取认证信息。
    • 设备在连接 EMQX 时,使用从 Go-Gin 获取的用户名和密码进行认证。
// Go-Gin 示例:设备注册接口
func registerDevice(c *gin.Context) {
    var device struct {
        DeviceID string `json:"device_id"`
        Username string `json:"username"`
        Password string `json:"password"`
    }
    if err := c.ShouldBindJSON(&device); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    // 保存设备信息到数据库
    saveDeviceInfo(device.DeviceID, device.Username, device.Password)

    c.JSON(http.StatusOK, gin.H{"message": "Device registered successfully"})
}

1.2 JWT 认证

  • EMQX 配置:配置 JWT 认证插件(如 emqx_auth_jwt)。
  • Go-Gin 实现
    • 提供一个 API 接口,用于生成 JWT Token。
    • 设备在连接 EMQX 时,使用从 Go-Gin 获取的 JWT Token 进行认证。
// Go-Gin 示例:生成 JWT Token
func generateToken(c *gin.Context) {
    var device struct {
        DeviceID string `json:"device_id"`
    }
    if err := c.ShouldBindJSON(&device); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    // 生成 JWT Token
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
        "device_id": device.DeviceID,
        "exp":       time.Now().Add(time.Hour * 24).Unix(),
    })
    tokenString, err := token.SignedString([]byte("your-secret-key"))
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"})
        return
    }

    c.JSON(http.StatusOK, gin.H{"token": tokenString})
}

2. 指令发送

指令发送是指通过 MQTT 协议向设备发送控制命令。EMQX 作为 MQTT 代理,负责消息的路由和传递。

2.1 设备订阅主题

设备在连接 EMQX 后,需要订阅一个特定的主题以接收指令。

// 设备订阅主题
client.Subscribe("device/command/"+deviceID, 1, nil)

2.2 Go-Gin 发送指令

Go-Gin 可以通过 MQTT 客户端库(如 paho.mqtt.golang)向设备发送指令。

// Go-Gin 示例:发送指令
func sendCommand(c *gin.Context) {
    var command struct {
        DeviceID string `json:"device_id"`
        Command  string `json:"command"`
    }
    if err := c.ShouldBindJSON(&command); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    // 发布指令到设备
    token := mqttClient.Publish("device/command/"+command.DeviceID, 1, false, command.Command)
    token.Wait()
    if token.Error() != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to send command"})
        return
    }

    c.JSON(http.StatusOK, gin.H{"message": "Command sent successfully"})
}

3. 业务处理

业务处理是指设备接收到指令后,执行相应的操作,并将结果反馈给服务器。

3.1 设备执行指令

设备在接收到指令后,执行相应的操作,并将结果发布到另一个主题。

// 设备执行指令并发布结果
client.Subscribe("device/command/"+deviceID, 1, func(client mqtt.Client, msg mqtt.Message) {
    command := string(msg.Payload())
    // 执行指令
    result := executeCommand(command)
    // 发布结果
    client.Publish("device/result/"+deviceID, 1, false, result)
})

3.2 Go-Gin 接收结果

Go-Gin 可以订阅设备的结果主题,接收设备执行指令后的反馈。

// Go-Gin 示例:接收设备结果
func receiveResult(c *gin.Context) {
    var result struct {
        DeviceID string `json:"device_id"`
        Result   string `json:"result"`
    }
    if err := c.ShouldBindJSON(&result); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    // 处理设备结果
    processResult(result.DeviceID, result.Result)

    c.JSON(http.StatusOK, gin.H{"message": "Result received successfully"})
}

4. 总结

通过 EMQX 和 Go-Gin 的结合,可以实现设备的认证、指令发送及业务处理。EMQX 负责消息的路由和传递,而 Go-Gin 负责业务逻辑的处理和 API 的提供。通过 MQTT 协议,设备与服务器之间可以实现高效的通信。