[FEAT] 整合 MQTT 資料流自動化與環境埠號修復
1. 整合 MQTT Gateway 並支援動態 Redis Key 前綴隔離,解決多環境衝突。 2. 修正本地開發環境與 Demo 環境的埠號映射 (80/8080) 與 Vite HMR (5175) 設定。 3. 更新 CI/CD 部署流程,新增自動同步程式碼至 MQTT Worker 與 Queue 容器。 4. 擴充 .env.example 以提供完整的 MQTT/EMQX 相關變數範本。 5. 更新模擬腳本以符合現有測試資料。
This commit is contained in:
parent
e3ad7dd44f
commit
bf43a33df3
12
.env.example
12
.env.example
@ -73,3 +73,15 @@ VITE_PORT=5175
|
|||||||
|
|
||||||
WWWGROUP=1000
|
WWWGROUP=1000
|
||||||
WWWUSER=1000
|
WWWUSER=1000
|
||||||
|
|
||||||
|
# MQTT / EMQX
|
||||||
|
MQTT_BROKER_ADDR=tcp://emqx:1883
|
||||||
|
MQTT_GATEWAY_CLIENT_ID=star-cloud-gateway
|
||||||
|
MQTT_REDIS_ADDR=redis:6379
|
||||||
|
MQTT_REDIS_PASSWORD=${REDIS_PASSWORD}
|
||||||
|
MQTT_INCOMING_QUEUE=mqtt_incoming_jobs
|
||||||
|
MQTT_OUTGOING_QUEUE=mqtt_outgoing_commands
|
||||||
|
|
||||||
|
# EMQX Ports (for local dev)
|
||||||
|
MQTT_PORT=1883
|
||||||
|
EMQX_DASHBOARD_PORT=18083
|
||||||
|
|||||||
@ -23,9 +23,9 @@ jobs:
|
|||||||
|
|
||||||
- name: Step 2 - Deploy Code
|
- name: Step 2 - Deploy Code
|
||||||
run: |
|
run: |
|
||||||
# Runner 容器模式下,volume mount 無法正確對應宿主機路徑
|
|
||||||
# 使用 docker cp 直接將程式碼注入容器(透過 Docker socket)
|
|
||||||
docker cp . star-cloud-laravel:/var/www/html/
|
docker cp . star-cloud-laravel:/var/www/html/
|
||||||
|
docker cp . star-cloud-queue:/var/www/html/
|
||||||
|
docker cp . star-cloud-mqtt-worker:/var/www/html/
|
||||||
docker exec star-cloud-laravel sh -c "
|
docker exec star-cloud-laravel sh -c "
|
||||||
chown -R 1000:1000 /var/www/html &&
|
chown -R 1000:1000 /var/www/html &&
|
||||||
mkdir -p /.npm && chown -R 1000:1000 /.npm &&
|
mkdir -p /.npm && chown -R 1000:1000 /.npm &&
|
||||||
|
|||||||
30
compose.yaml
30
compose.yaml
@ -15,6 +15,7 @@ services:
|
|||||||
- '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
|
- '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
|
||||||
environment:
|
environment:
|
||||||
WWWUSER: '${WWWUSER}'
|
WWWUSER: '${WWWUSER}'
|
||||||
|
SUPERVISOR_PHP_COMMAND: "/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80"
|
||||||
LARAVEL_SAIL: 1
|
LARAVEL_SAIL: 1
|
||||||
XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
|
XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
|
||||||
XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
|
XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
|
||||||
@ -45,6 +46,24 @@ services:
|
|||||||
- mysql
|
- mysql
|
||||||
- redis
|
- redis
|
||||||
restart: always
|
restart: always
|
||||||
|
laravel.mqtt:
|
||||||
|
image: 'sail-8.5/app'
|
||||||
|
container_name: star-cloud-mqtt-worker
|
||||||
|
hostname: star-cloud-mqtt-worker
|
||||||
|
command: php artisan mqtt:listen
|
||||||
|
environment:
|
||||||
|
WWWUSER: '${WWWUSER}'
|
||||||
|
LARAVEL_SAIL: 1
|
||||||
|
TZ: 'Asia/Taipei'
|
||||||
|
volumes:
|
||||||
|
- '.:/var/www/html'
|
||||||
|
networks:
|
||||||
|
- sail
|
||||||
|
depends_on:
|
||||||
|
- mysql
|
||||||
|
- redis
|
||||||
|
- emqx
|
||||||
|
restart: always
|
||||||
|
|
||||||
mysql:
|
mysql:
|
||||||
image: 'mysql/mysql-server:8.0'
|
image: 'mysql/mysql-server:8.0'
|
||||||
@ -119,12 +138,13 @@ services:
|
|||||||
container_name: star-cloud-mqtt-gateway
|
container_name: star-cloud-mqtt-gateway
|
||||||
hostname: mqtt-gateway
|
hostname: mqtt-gateway
|
||||||
environment:
|
environment:
|
||||||
MQTT_BROKER_ADDR: 'tcp://emqx:1883'
|
MQTT_BROKER_ADDR: '${MQTT_BROKER_ADDR:-tcp://emqx:1883}'
|
||||||
MQTT_GATEWAY_CLIENT_ID: 'star-cloud-gateway'
|
MQTT_GATEWAY_CLIENT_ID: '${MQTT_GATEWAY_CLIENT_ID:-star-cloud-gateway}'
|
||||||
MQTT_REDIS_ADDR: 'star-cloud-redis:6379'
|
MQTT_REDIS_ADDR: '${MQTT_REDIS_ADDR:-redis:6379}'
|
||||||
MQTT_REDIS_PASSWORD: '${REDIS_PASSWORD:-}'
|
MQTT_REDIS_PASSWORD: '${REDIS_PASSWORD:-}'
|
||||||
MQTT_INCOMING_QUEUE: 'mqtt_incoming_jobs'
|
MQTT_REDIS_PREFIX: '${MQTT_REDIS_PREFIX:-starcloud_database_}'
|
||||||
MQTT_OUTGOING_QUEUE: 'mqtt_outgoing_commands'
|
MQTT_INCOMING_QUEUE: '${MQTT_INCOMING_QUEUE:-mqtt_incoming_jobs}'
|
||||||
|
MQTT_OUTGOING_QUEUE: '${MQTT_OUTGOING_QUEUE:-mqtt_outgoing_commands}'
|
||||||
TZ: 'Asia/Taipei'
|
TZ: 'Asia/Taipei'
|
||||||
networks:
|
networks:
|
||||||
- sail
|
- sail
|
||||||
|
|||||||
@ -14,6 +14,9 @@ RUN CGO_ENABLED=0 go build -o gateway .
|
|||||||
# Stage 2: Run
|
# Stage 2: Run
|
||||||
FROM alpine:3.20
|
FROM alpine:3.20
|
||||||
|
|
||||||
|
# 安裝 tzdata 以支援時區設定
|
||||||
|
RUN apk add --no-cache tzdata
|
||||||
|
|
||||||
WORKDIR /root/
|
WORKDIR /root/
|
||||||
COPY --from=builder /app/gateway .
|
COPY --from=builder /app/gateway .
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@ type Config struct {
|
|||||||
RedisPassword string
|
RedisPassword string
|
||||||
IncomingQueueKey string
|
IncomingQueueKey string
|
||||||
OutgoingQueueKey string
|
OutgoingQueueKey string
|
||||||
|
RedisPrefix string
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadConfig() *Config {
|
func LoadConfig() *Config {
|
||||||
@ -21,6 +22,7 @@ func LoadConfig() *Config {
|
|||||||
RedisPassword: getEnv("MQTT_REDIS_PASSWORD", ""),
|
RedisPassword: getEnv("MQTT_REDIS_PASSWORD", ""),
|
||||||
IncomingQueueKey: getEnv("MQTT_INCOMING_QUEUE", "mqtt_incoming_jobs"),
|
IncomingQueueKey: getEnv("MQTT_INCOMING_QUEUE", "mqtt_incoming_jobs"),
|
||||||
OutgoingQueueKey: getEnv("MQTT_OUTGOING_QUEUE", "mqtt_outgoing_commands"),
|
OutgoingQueueKey: getEnv("MQTT_OUTGOING_QUEUE", "mqtt_outgoing_commands"),
|
||||||
|
RedisPrefix: getEnv("MQTT_REDIS_PREFIX", "starcloud_database_"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 加入 Laravel 前綴,確保雙方桶子同一個
|
// 加入 Laravel 前綴,確保雙方桶子同一個
|
||||||
prefixedIncomingKey := "starcloud_database_" + cfg.IncomingQueueKey
|
prefixedIncomingKey := cfg.RedisPrefix + cfg.IncomingQueueKey
|
||||||
pusher := bridge.NewRedisPusher(rdb, prefixedIncomingKey)
|
pusher := bridge.NewRedisPusher(rdb, prefixedIncomingKey)
|
||||||
mqttHandler := handler.NewMqttHandler(pusher)
|
mqttHandler := handler.NewMqttHandler(pusher)
|
||||||
|
|
||||||
@ -76,7 +76,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3. 啟動 Redis Consumer (下行指令)
|
// 3. 啟動 Redis Consumer (下行指令)
|
||||||
consumer := bridge.NewRedisConsumer(rdb, client, cfg.OutgoingQueueKey)
|
prefixedOutgoingKey := cfg.RedisPrefix + cfg.OutgoingQueueKey
|
||||||
|
consumer := bridge.NewRedisConsumer(rdb, client, prefixedOutgoingKey)
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
go consumer.Start(ctx)
|
go consumer.Start(ctx)
|
||||||
|
|
||||||
|
|||||||
@ -7,8 +7,8 @@
|
|||||||
# 依賴:Docker (使用 eclipse-mosquitto 鏡像進行發送)
|
# 依賴:Docker (使用 eclipse-mosquitto 鏡像進行發送)
|
||||||
# =================================================================
|
# =================================================================
|
||||||
|
|
||||||
SERIAL_NO="SN00001"
|
SERIAL_NO="M000001"
|
||||||
API_TOKEN="8QwOrmKX6sLmR5T1sChfvGjfc8eS4qaclOFd4ocItmeryii7SFqcC5uMpnzg"
|
API_TOKEN="VfFFb0DIUqtLTPF4jyCsB2h5fWsMcVxCPboNHpKc3XzRComLEK07xFYRUzBJ"
|
||||||
TOPIC="machine/${SERIAL_NO}/heartbeat"
|
TOPIC="machine/${SERIAL_NO}/heartbeat"
|
||||||
NETWORK="star-cloud_sail"
|
NETWORK="star-cloud_sail"
|
||||||
BROKER_HOST="emqx"
|
BROKER_HOST="emqx"
|
||||||
|
|||||||
@ -2,6 +2,14 @@ import { defineConfig } from 'vite';
|
|||||||
import laravel from 'laravel-vite-plugin';
|
import laravel from 'laravel-vite-plugin';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
server: {
|
||||||
|
hmr: {
|
||||||
|
host: 'localhost',
|
||||||
|
},
|
||||||
|
host: '0.0.0.0',
|
||||||
|
port: 5175,
|
||||||
|
strictPort: true,
|
||||||
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
laravel({
|
laravel({
|
||||||
input: [
|
input: [
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user