【物联网】MQTT / Broker / Topic 是什么?


1) MQTT / Broker / Topic 是什么?在你项目里怎么用

  • MQTT 是轻量级发布/订阅消息协议 :设备把消息"发布(publish)"到某个主题(topic) ;任何"订阅(subscribe)"了该主题的客户端都会收到消息;中间的Broker(代理服务器)只负责接收并转发消息。课件明确了这是 IoT 中常用的架构,并给了 Publish/Subscribe 的示意。

  • 本课使用 AWS EC2 自建 Mosquitto 作为 Broker :在 EC2 上安装 mosquitto/mosquitto-clients,启用并启动服务(systemctl enable/start mosquitto),就能作为 MQTT Broker 收发消息。

  • 要让外网可以访问,需要两处设置:

    1. Security Group 放通 TCP 1883 (明文 MQTT;若走 TLS 是 8883)到 0.0.0.0/0;课件截图特别强调 SG 里"Allows MQTT traffic from anywhere (1883; 8883)"。

    2. 在 /etc/mosquitto/mosquitto.conf 加:

      复制代码
      listener 1883 0.0.0.0
      allow_anonymous true

      然后 systemctl restart mosquitto;并可用 ss -ltnp | grep 1883 检查端口监听。

  • 快速自测命令(课件也给了):

    • 订阅:mosquitto_sub -h <EC2_public_IP> -t test
    • 发布:mosquitto_pub -h <EC2_public_IP> -t test -m "hello"

你的截图里 EC2 的 Public IPv4 是 1xxxx 。把它放进 Python 里当 MQTT_HOST,外网(校园网、家庭网等)都能连到你的 Broker,只要 SG 和 mosquitto.conf 按上面配置好了。


2) 你的完整数据管道:如何映射到代码

课件在 Practical #5 里把 A1 的上下行两条链路讲得很清楚:

  • 上行(Uplink) :Arduino(BLE Peripheral)→ BLE Notify → Raspberry Pi(Python/bleak)→ MQTT Publish → Broker(EC2)。
  • 下行(Downlink) :云端或手机 → MQTT Publish 命令 → Pi 订阅 到命令 → Pi 用 BLE Write 写回 Arduino → Arduino 控制执行器(LED)。

在你的两份代码里,正好是一一对应的:

Arduino(Nano 33 IoT,BLE 外设)

  • GATT 设计

    • Service UUID :f75cfb20-...e2f5
    • Sensor Characteristic :f75cfb21-...e2f5(Read | Notify)------上行数据口
    • Command Characteristic :f75cfb22-...e2f5(Write )------下行命令口
      这就是课件建议的"多特征、分工明确"的做法,利于拿满分。
  • 上行实现

    • 周期性(每 6s)读取 DHT11 ,用 ArduinoJson 组装 JSON:{temperature, humidity, timestamp, device_id};
    • 把 JSON 写入 Notify 特征 :sensorCharacteristic.writeValue(json),Central 若订阅了就会收到通知。
  • 下行实现

    • 只要 Central 对 Write 特征 写入(commandCharacteristic.written() 为真),就解析 JSON({"led":"on/off/toggle"})或纯文本(LED_ON/LED_OFF),并控制板载 LED。

这部分正是 A1「Send the data to RPi via BLE 」「Receive commands from RPi 」「Operate actuators (LED)」的评分点。

Raspberry Pi(Python,bleak + paho-mqtt)

  • BLE(bleak)部分

    • 扫描并连接 :BleakScanner.find_device_by_filter(lambda d: d.name and DEVICE_NAME in d.name);
    • 订阅上行数据 :client.start_notify(SENSOR_CHAR_UUID, on_ble_notify);
    • 收到 Notify 后 ,回调 on_ble_notify 把 payload publish 到 MQTT。
  • MQTT(paho-mqtt)部分

    • mqtt.Client(...).connect(MQTT_HOST, MQTT_PORT) 与 Broker 建连;
    • 订阅命令主题 (iot/commands/arduino):回调 on_mqtt_message 把命令 JSON 原样 BLE write 到 COMMAND_CHAR_UUID;
  • 这正是课件"把 BLE 与 MQTT 拼到一起"的桥接方式(上行 bleread_mqttpub;下行 mqttsub_blewrite)。你已经把它们合成到一个脚本里了,结构更清晰。


3) 代码里"Broker/MQTT/Topic"的具体体现

以你的 Python 为例(省略无关行,只看 MQTT 相关):

py 复制代码
MQTT_HOST   = "13.236.187.137"   # 你的 EC2 公网 IP
MQTT_PORT   = 1883               # mosquitto 默认端口(明文)

TOPIC_SENSOR = "iot/sensors/data"     # 上行主题:Pi 发布
TOPIC_CMD    = "iot/commands/arduino" # 下行主题:Pi 订阅

mqtt_client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
mqtt_client.on_message = on_mqtt_message
mqtt_client.connect(MQTT_HOST, MQTT_PORT, 60)
mqtt_client.subscribe(TOPIC_CMD)      # 订阅命令
mqtt_client.loop_start()

# 上行发布:在 BLE 回调里
mqtt_client.publish(TOPIC_SENSOR, payload)
  • MQTT_HOST/MQTT_PORT 指向Broker(EC2 上的 mosquitto);课件中也使用相同端口并强调先放通安全组与 broker 配置。
  • TOPIC_SENSOR / TOPIC_CMD 是你定义的主题 (可以自取层级结构);课件也建议用分层命名和通配符做调试,例如 ifn649/#。
  • 你的 上行 是"BLE Notify → 回调 → publish";下行 是"订阅 → 回调 → write_gatt_char"。这与课件的 E2E Pipeline 完全一致。

4) AWS EC2 端的最小可用配置(对照你的截图)

  1. 创建/启动实例 后,确认 Security Group 里:

    • Inbound 允许 TCP 22(SSH,校网段已预设);
    • 允许 TCP 1883(0.0.0.0/0),若做 TLS 再开放 8883。
  2. 首次 SSH(确保 .pem 权限是 400),连接到公网 IP (如 13.236.187.137),执行:

    bash 复制代码
    sudo apt update && sudo apt upgrade -y
    sudo apt install -y mosquitto mosquitto-clients
    sudo systemctl enable mosquitto
    sudo systemctl start mosquitto
  3. 打开外部监听与匿名访问(课堂环境):

    bash 复制代码
    sudo nano /etc/mosquitto/mosquitto.conf
    # 添加:
    listener 1883 0.0.0.0
    allow_anonymous true
    sudo systemctl restart mosquitto
    sudo ss -ltnp | grep 1883
  4. 本地或手机自测:

    • mosquitto_sub -h 13.236.187.137 -t iot/sensors/data(先开订阅窗口)
    • 运行你的 Python,看到订阅窗口里出现 Arduino 上来的 JSON;
    • 用手机 MyMQTT 连接 13.236.187.137:1883,往 iot/commands/arduino 发 {"led":"on"},观察板载 LED 亮起。

若你把 Python 里 MQTT_HOST 误写成 私网 IP(172.31.x.x) ,则校园网/家庭网无法直连 (除非你的 Pi 也在同一 VPC),因此要用Public IPv4。这也是课件"外部访问需要开放 1883 并配置 broker 外部监听"的原因。


5) 与评分点的对齐(快速核对)

  • Collect data from DHT-11 :dht.readHumidity()/readTemperature();失败打印"DHT sensor read failed!"。
  • Send the data to RPi via BLE :sensorCharacteristic(Notify)+ 周期 6s 上报 JSON。
  • Receive commands from RPi :commandCharacteristic.written() + JSON/文本命令解析。
  • Operate actuators (LED) :digitalWrite(LED_PIN, HIGH/LOW) 对应 {"led":"on/off/toggle"}。
  • RPi 端:bleak 读写 + paho-mqtt 发布/订阅,完成"Read data via BLE / Publish to MQTT / Receive subscribed topics / Send commands to Arduino"。这些正是 Practical #5 的 E2E 要求。

小结 / 你现在要做的事

  1. 确保 EC2 :Security Group 放通 1883;mosquitto 已安装并监听 0.0.0.0:1883。
  2. 把 Python 的 MQTT_HOST 设为 1xxx.137(你的截图里公有 IP)。
  3. 先开一个订阅窗口 观察:mosquitto_sub -h 13.236.187.137 -t iot/sensors/data。
  4. 烧录 Arduino (你贴的最新 ino 没问题);再运行 Python 桥接脚本。
  5. 手机/MyMQTT 或命令行 向 iot/commands/arduino 发 {"led":"on"}/{"led":"off"},观察板载 LED 响应。
相关推荐
Chery11402 小时前
BLE + Wi-Fi双模智能家居方案:ESP32-C3FH4&ESP32-C5HF4芯片选型指南
物联网·ai·智能家居
白帽攻防录2 小时前
SRC 挖洞:QUIC 协议栈双 RCE,HTTP/3 的新攻击面怎么挖
网络·网络协议·http·网络安全·http/3
墨云安全2 小时前
AI 漏洞挖掘平台怎么评估?2026 年技术架构与选型要点
网络·人工智能·网络安全·架构·渗透测试
红姐跨境书2 小时前
TikTok 爬虫实战指南:避开 TikTok 反爬机制的 7个坑
网络
隐擎fox2 小时前
Linux eBPF 与 XDP 高性能网络出口架构:动态连接追踪、丢包诊断与住宅网关 QoS 调优实战
linux·网络·网络协议·tcp/ip·架构
Multipath7123 小时前
多链路聚合设备:助力智慧农业发展的网络基石——让农田网络不断连,让智能设备不失控
网络·网络协议·5g·udp·无人机
似是燕归来3 小时前
Rtthread OS 功能开发之 socket udp协议程序开发
网络·stm32·网络协议·udp·socket·rtthread
饿了吃洗衣凝珠3 小时前
red hot day1
网络
牧羊人.3333 小时前
自然语言处理基础 04|长短期记忆网络 LSTM
网络·人工智能·rnn·深度学习·学习·自然语言处理·lstm
lambo mercy3 小时前
Day4:流式传输
运维·服务器·网络