star-cloud/mqtt-gateway/internal/bridge/redis_consumer.go
sky121113 959625a640 [FEAT] 實作 MQTT Gateway 整合與高併發 IoT 通訊架構
1. 導入 Go 語言撰寫的 MQTT Gateway (mqtt-gateway/),負責訊息接收並透過 Redis List 轉發至 Laravel。
2. 更新 compose.yaml 以包含 EMQX Broker 與 mqtt-gateway 服務,並配置相關環境變數。
3. 新增 ListenMqttQueue 指令與對應的異步處理 Job (ProcessHeartbeat, ProcessTransaction, ProcessMachineError)。
4. 實作 MqttSyncAuth 指令與 Machine Model Observer,支援自動化的機台認證資訊同步至 Redis。
5. 新增 MqttCommandService 用於處理雲端至機台的即時指令下發。
6. 更新專案規範文件 (framework.md 與 Skills) 以反映新的 MQTT 通訊機制與安全性規範。
7. 提供 simulate-heartbeat.sh 指令碼以供開發與測試使用。
2026-04-16 14:28:42 +08:00

63 lines
1.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package bridge
import (
"context"
"encoding/json"
"log"
mqtt "github.com/eclipse/paho.mqtt.golang"
"github.com/redis/go-redis/v9"
)
type RedisConsumer struct {
rdb *redis.Client
mqttClient mqtt.Client
queueKey string
}
type CommandPayload struct {
Target string `json:"target"`
Command string `json:"command"`
Payload interface{} `json:"payload"`
MessageID string `json:"message_id"`
}
func NewRedisConsumer(rdb *redis.Client, mqttClient mqtt.Client, queueKey string) *RedisConsumer {
return &RedisConsumer{rdb: rdb, mqttClient: mqttClient, queueKey: queueKey}
}
func (c *RedisConsumer) Start(ctx context.Context) {
log.Printf("Redis Consumer started, listening on queue: %s", c.queueKey)
for {
select {
case <-ctx.Done():
return
default:
// 使用 BLPOP 阻塞式讀取,逾時設為 0 表示永久等待
result, err := c.rdb.BLPop(ctx, 0, c.queueKey).Result()
if err != nil {
if err != context.Canceled {
log.Printf("Redis BLPop error: %v", err)
}
continue
}
// result[0] 是 keyresult[1] 是 value
var cmd CommandPayload
err = json.Unmarshal([]byte(result[1]), &cmd)
if err != nil {
log.Printf("Failed to unmarshal command: %v", err)
continue
}
topic := "machine/" + cmd.Target + "/command"
payload, _ := json.Marshal(cmd)
token := c.mqttClient.Publish(topic, 1, false, payload)
token.Wait()
log.Printf("Sent command [%s] to machine [%s] via topic: %s", cmd.Command, cmd.Target, topic)
}
}
}