资讯动态

MQTT协议从入门到实践:物联网消息通信核心机制详解

发布时间:2026/10/25 3:43:48 来源:尧图企业网站定制
1. 为什么学物联网要先弄懂MQTT一个消息协议的前世今生1.1 从串口到网络设备之间到底怎么说话搞嵌入式或者物联网的朋友多半是从串口起步的。单片机之间通信用UART一条TX一条RX波特率约定好数据帧的格式自己定义两边就能聊起来。这种点对点的通信方式很直观也很可靠但它有个天然限制一台设备只能跟跟自己物理连着的设备说话而且距离一远、节点一多线都拉不过来。到了物联网阶段设备要联网要走Wi-Fi、走4G/5G、走以太网通信模型就变了。网络是分组交换的不是一根线直连天然就适合多对多的通信。但问题也来了A设备要把数据给B设备怎么知道B的网络地址B断线了怎么办A和B不在同一个局域网中间隔着路由器甚至公网怎么把消息送过去这些问题如果每个项目都自己造轮子光处理连接管理和消息路由就够喝一壶的。MQTT就是在这个背景下被设计出来的协议专门解决大量设备、网络不稳定、带宽有限场景下的消息分发问题。1.2 MQTT的诞生背景低带宽、不可靠网络下的消息协议MQTT的全称是Message Queuing Telemetry Transport消息队列遥测传输。注意遥测这个词它暗示了设计初衷收集远端设备的状态数据。最早是上个世纪末某大型工业设备厂商为了让数万条管道上的传感器数据能回传到监控中心设计了这套协议。它从出生就不是给高大上的场景用的而是奔着低带宽、高延迟、网络频繁断开的恶劣环境去的。这套设计哲学体现在很多细节里。比如MQTT的报文头非常紧凑固定报头最少只要两个字节。一条带主题的发布消息在payload很少的情况下整体也就十几个字节。对比一下HTTP光是请求头里那一堆字段就够发好几条MQTT消息了。再比如MQTT做了心跳保活机制KeepAlive客户端每隔一段时间给服务端发一个PINGREQ双方都知道对方还活着。网络断了双方能在很短的时间内感知到而不是傻等超时。这些特性放到今天来看成了物联网场景下的标准答案。1.3 为什么不是HTTP一次请求/响应模型在物联网场景的局限很多人学物联网时会有个疑问Web开发我熟为什么不直接用HTTP设备把数据POST到一个服务器接口不就行了单从发数据这个动作看确实可以。HTTP是请求/响应模型客户端发一个请求服务端回一个响应一次交互就结束了。但物联网的真实场景比这复杂得多控制指令下发服务器要主动通知设备开灯关阀。HTTP是客户端主动发起请求的服务器没法主动往设备上推数据除非设备不停地轮询既浪费流量又不够实时。多设备联动一个传感器数据要同时给好几个下游系统用HTTP要写多个转发逻辑而MQTT天然是一份消息广播给所有订阅者。弱网恢复HTTP的请求做不到消息没送到我帮你缓存一下等设备上线了再补发。MQTT的QoS机制和会话管理可以做到。这么说吧HTTP解决的是人访问网站的问题而MQTT解决的是设备之间、设备与系统之间互相信号的问题。它俩不是替代关系而是不同场景下的合适工具。理解到这一层再上手MQTT就会顺很多。2. 拆开MQTT的包发布/订阅模型、Broker和Topic到底是怎么回事2.1 快递中转站模式Broker的角色与价值MQTT的核心模型是发布/订阅Publish/Subscribe所有消息都经过一个中间人这个中间人叫Broker消息代理。你可以把它想象成快递中转站寄件人发布者不用知道收件人订阅者住在哪儿只要把包裹扔给中转站写上主题标签Topic中转站会根据标签把包裹分发给所有订阅了这个标签的人。这套模型解决了端到端通信最大的痛点解耦。发布者不需要知道订阅者的IP地址、端口、在线状态订阅者也不需要知道发布者是谁。所有人都只跟Broker打交道Broker负责路由、存储、转发。设备A和B不在同一个网络甚至一个是公网一个是私网只要它们都能连上同一个Broker消息就能互通。做过点对点Socket通信的人应该深有体会NAT穿透这种事有多烦而MQTT直接把这个复杂度从应用层抽掉了。Broker本身也有多种实现。开发阶段最常用的是开源的Mosquitto轻量、配置简单跑在一台树莓派或者云服务器上都很轻松。生产环境对性能和集群有要求的话可以考虑EMQX这类基于Erlang的Broker支持百万级连接我自己的项目规模没那么大目前长期用的是Mosquitto稳定得让人几乎感觉不到它的存在。2.2 Topic不是文件夹主题层级与通配符的正确理解Topic是MQTT消息的地址但它不是IP地址那种扁平结构而是用斜杠分隔的层级结构比如sensor/room1/temperature sensor/room1/humidity device/gateway/status这个结构很容易让人联想到文件系统的目录初学者也常拿文件夹来类比。但我要提醒一句这个类比有一半是对的一半会误导你。Topic不是预先创建出来的实体它的层级是软的不需要像文件夹那样先mkdir才能写文件。发布者直接往sensor/room1/temperature发消息这个Topic就存在了Broker不需要任何配置。所以更准确的类比是逻辑命名空间大家约定好命名规则消息就能按规则路由。层级结构真正的价值在于支持通配符订阅。MQTT有两个通配符匹配单层。比如订阅sensor//temperature可以收到sensor/room1/temperature和sensor/room2/temperature的消息但收不到sensor/room1/floor1/temperature。#匹配多层必须放在最后。比如订阅sensor/#就能收到sensor/room1/temperature、sensor/room1/floor1/temperature等所有以sensor/开头的消息。我见过不少人在设计Topic规范时没想清楚层级后面扩展的时候很痛苦。建议从一开始就按设备位置/设备类型/数据类型这种稳定的粒度来设计比如sensor/{房间}/{数据类型}避免把设备ID这种会变的字段放在靠前的层级里。2.3 一次完整的消息旅程connect、publish、subscribe的信令流程MQTT的通信建立在TCP连接之上默认端口是1883TLS加密版本是8883。整个交互流程可以归结为三类报文CONNECT/CONNACK客户端先发CONNECT报文带上ClientID、用户名密码、KeepAlive时长、Clean Session标志等信息。Broker校验通过后回CONNACK。这里的ClientID必须是唯一的我之前用固定字符串做ClientID导致两个设备同时连接时后一个把前一个踢下线排查了半天才意识到是ClientID撞了。SUBSCRIBE/SUBACK客户端告诉Broker我对这些Topic感兴趣Broker收到后返回SUBACK确认订阅成功。PUBLISH/PUBACK发布者发PUBLISH报文里面有Topic和Payload消息体通常是JSON文本或二进制数据。QoS为1时Broker需要回PUBACK确认QoS为2时则有更复杂的两段握手。此外还有PINGREQ/PINGRESP用于心跳保活DISCONNECT用于正常断开。理解了这几类报文MQTT就不再是玄学所有客户端库的API本质上都是在封装这些报文交互。我建议新手去Wireshark里抓一次包亲眼看一下CONNECT报文的字段结构比看十遍文档都有用。3. 动手搭一个最小可用环境从Mosquitto到第一个发布订阅Demo3.1 环境准备Broker安装与本机验证纸上谈兵没意思直接动手搭环境。我在一台长期开机的小主机上装了Mosquitto系统是Debian系的安装命令很简单sudo apt update sudo apt install -y mosquitto mosquitto-clients装完默认就会以系统服务方式跑起来。先别急着改配置用默认配置验证一下Broker是否正常sudo systemctl status mosquitto看到active (running)就说明Broker起来了。这时可以确认一下1883端口是否在监听ss -tlnp | grep 1883如果看到类似0.0.0.0:1883的监听地址说明Mosquitto已经准备好接收连接了。默认配置下Mosquitto只监听本地回环地址还是所有接口不同版本略有差异后面做局域网测试时如果连不上记得检查监听地址和防火墙。3.2 用命令行客户端模拟两个设备对话安装mosquitto-clients之后我们有了两个命令mosquitto_pub和mosquitto_sub。它们分别是命令行版的发布者和订阅者。打开第一个终端订阅一个主题mosquitto_sub -h 127.0.0.1 -t test/topic -v参数-v表示把收到的消息连同主题一起打印出来。再开第二个终端发布一条消息mosquitto_pub -h 127.0.0.1 -t test/topic -m hello mqtt如果一切正常第一个终端会立刻打印出test/topic hello mqtt看到这行输出恭喜你你的第一个MQTT消息已经完整走了一遍发布者 - Broker - 订阅者的链路。整个过程没有写一行代码这恰恰说明了MQTT的简洁和可调试性。3.3 订阅确认与消息路径验证怎么判断消息真的到了初学阶段有个容易困惑的地方怎么确认消息真的经过了Broker转发而不是两个进程恰好都连到了同一个地方一种方法是在订阅时加上-v查看完整输出另一种是使用mosquitto_sub的--help里的调试选项。更直接的办法是同时开三个终端一个订阅test/#一个订阅test/topic一个发布消息然后观察两个订阅端是否都能收到。如果都能收到说明Broker确实在做一份消息多份分发的工作而不是简单的点对点传输。另外一个值得做的验证是用mosquitto_pub发布一条消息时如果当前没有任何订阅者消息会被丢弃。你再发布一次然后再开订阅这次订阅端不会收到之前那条消息。这是因为MQTT默认不是消息队列不会为离线订阅者缓存消息除非用持久会话QoS1/2。这个特性在调设备联动时会坑人我们后面会专门讲应对方案。4. 用Python写一个温湿度自动上报器代码注解级别的完整实操4.1 为什么选paho-mqtt库的基本使用逻辑命令行验证完协议的运转原理接下来要做正事了。我用Python写过多个设备的接入Demo最顺手的客户端库是paho-mqtt。选择它有几个原因首先是API设计贴近协议本身的术语connect、publish、subscribe、on_message回调几乎不需要抽象层的心智负担其次是文档全、坑少社区用的人多出问题很容易搜到答案。安装很简单pip install paho-mqtt它的核心用法是创建客户端对象绑定事件回调连接Broker然后进入网络循环loop。paho库提供了一个loop_forever()阻塞方法也提供loop_start()在后台线程跑网络循环。我的习惯是主程序里用loop_forever()配合on_connect、on_message这些回调来驱动业务逻辑代码结构很清晰。4.2 完整代码发布端与订阅端先写一个模拟温湿度传感器的发布端。我这里用一个随机数函数模拟传感器读数真实项目中替换成读取DHT11或者SHT30传感器的代码即可import random import time import json import paho.mqtt.client as mqtt BROKER_HOST 127.0.0.1 BROKER_PORT 1883 CLIENT_ID sensor-simulator-01 TOPIC_TEMP sensor/room1/temperature TOPIC_HUMI sensor/room1/humidity PUBLISH_INTERVAL 5 # 每5秒上报一次 def on_connect(client, userdata, flags, rc): if rc 0: print(连接Broker成功) else: print(f连接失败返回码{rc}) def on_disconnect(client, userdata, rc): print(f连接断开rc{rc}) def create_client(): client mqtt.Client(client_idCLIENT_ID, clean_sessionTrue) client.on_connect on_connect client.on_disconnect on_disconnect client.connect(BROKER_HOST, BROKER_PORT, keepalive60) client.loop_start() return client def read_sensor(): # 模拟温湿度传感器读数 temperature round(20 random.random() * 10, 2) humidity round(40 random.random() * 30, 2) return temperature, humidity def main(): client create_client() while True: temp, humi read_sensor() payload_temp json.dumps({value: temp, unit: celsius}) payload_humi json.dumps({value: humi, unit: percent}) client.publish(TOPIC_TEMP, payload_temp, qos1) client.publish(TOPIC_HUMI, payload_humi, qos1) print(f已上报温度{temp}℃ 湿度{humi}%) time.sleep(PUBLISH_INTERVAL) if __name__ __main__: main()这里有两个细节值得说。第一clean_sessionTrue表示每次连接都是全新会话Broker不保留之前的订阅和离线消息。开发调试阶段用这个比较省心。第二client.publish()只是把消息交给网络循环去发送并不是同步阻塞的如果要确认确实发出去了可以检查publish()返回的对象里的rc值。这个例子为了简洁没做严格校验真实项目建议加。然后是订阅端的代码负责接收数据并做展示import json import paho.mqtt.client as mqtt BROKER_HOST 127.0.0.1 BROKER_PORT 1883 CLIENT_ID dashboard-subscriber-01 TOPIC_TEMP sensor/room1/temperature TOPIC_HUMI sensor/room1/humidity def on_connect(client, userdata, flags, rc): if rc 0: print(订阅端连接成功) client.subscribe([(TOPIC_TEMP, 1), (TOPIC_HUMI, 1)]) else: print(f连接失败返回码{rc}) def on_message(client, userdata, msg): try: data json.loads(msg.payload.decode(utf-8)) if msg.topic TOPIC_TEMP: print(f[温度] {data[value]} {data[unit]}) elif msg.topic TOPIC_HUMI: print(f[湿度] {data[value]} {data[unit]}) except (json.JSONDecodeError, KeyError) as e: print(f消息解析失败{e}原始内容{msg.payload}) def main(): client mqtt.Client(client_idCLIENT_ID, clean_sessionTrue) client.on_connect on_connect client.on_message on_message client.connect(BROKER_HOST, BROKER_PORT, keepalive60) client.loop_forever() if __name__ __main__: main()先跑订阅端再跑发布端你会在订阅端窗口看到每5秒打印一条温湿度数据一条消息从模拟传感器到展示端就完全打通了。4.3 真实设备接入的模拟数据采集、转换与定时上报的设计上面这段代码是可运行的但离真实设备接入还有一段距离。真正的传感器接入通常要考虑三个问题数据采集的准确性。模拟用的是random.random()真实场景里读DHT11这类温湿度传感器需要按数据手册的时序去操作采集到的原始值往往还要做校准。我在一个项目里用过一个便宜的温度传感器读出来的值比标准温度计高了大概2度后来在软件里做了偏移修正。这类经验告诉我们传感器数据本身不可尽信采集层的校正逻辑要预留接口。数据格式的约定。我用JSON作为Payload的格式字段名是value和unit。这个看起来很简单但恰恰是项目里最容易吵架的地方。发布端和订阅端必须对字段名、单位、值域达成一致否则就是字符串层面能通、业务层面全乱。我建议从第一个Demo开始就建立一份简单的Topic与Payload规范文档哪怕写在一页纸上后面接设备的时候能少很多返工。上报节奏的设计。定时上报5秒一次用于演示没问题但真实场景要考虑频率和负载的平衡。温度这种缓变数据30秒上报一次都足够而门磁、人体红外这类事件型数据应该用变化时上报而不是定时上报。MQTT本身不限制上报频率但高频上报会占用Broker资源、消耗设备电量和流量。对电池供电的设备来说每次发送都是一次射频开销这直接关系到续航。合理的设计往往是在设备端做阈值判断数值变化超过一定范围才上报。5. QoS、遗嘱消息与保留消息这几个隐藏功能关键时刻救命5.1 QoS 0/1/2三档送达保证到底差在哪MQTT的QoSQuality of Service服务质量是绕不开的概念它定义了消息从发布者到订阅者的送达保证等级等级名称送达保证开销QoS 0至多一次消息可能丢失不确认最低QoS 1至少一次消息保证送达但可能重复中QoS 2恰好一次消息不丢不重最高网上很多文章把QoS解释得玄乎我这里用最直白的话拆解。QoS 0就是发出去不管适合温度这种丢了下一轮还有的数据。QoS 1是发送后等Broker回一个PUBACK收不到就重发所以可能重复订阅端要自己做去重。QoS 2最严格通过两段握手确保让Broker只接收一次适合控制指令、支付通知这类不能重复也不能丢的消息。实际开发里我90%的场景用QoS 1因为它平衡了可靠性和效率。QoS 2虽然保证最强但握手流程复杂、吞吐量低不是必要不用。QoS 0用的地方也有比如高频的遥测数据丢了就丢了重发反而挤占带宽。有一点尤其需要注意QoS等级是发布和订阅两侧共同决定的实际生效等级取两者中的最小值。发布端用了QoS 2订阅端如果订阅时写的是QoS 0那消息实际按QoS 0的待遇分发。这个细节容易让人误以为我发布用QoS 2就万事大吉。5.2 Retained Message新来的订阅者为什么能看到上一条数据默认情况下消息发出去如果没有订阅者在线消息就没了。这带来一个很实际的问题设备状态类信息比如门现在是开着还是关着灯是亮着还是灭了新接入的订阅者根本不知道当前状态。让每个新订阅者都去主动查询一次也不现实因为发布者可能不在线。MQTT的Retained Message保留消息机制就是为这个场景设计的。发布消息时把retain标志设为TrueBroker除了正常分发之外还会把这条消息存成该Topic最后一条消息。之后任何客户端订阅这个TopicBroker都会立刻把保留消息推送给它。拿前面温湿度的例子来说把发布代码改成client.publish(TOPIC_TEMP, payload, qos1, retainTrue)那么新开的订阅端一订阅就能立刻拿到当前温度值而不需要等下一个上报周期。这个机制在做状态同步时特别好用我在控制类项目里每个设备的上报消息都带retain这样上位机重启后不需要向每台设备发查询指令就能恢复全部状态的记忆。5.3 Last Will设备猝死时如何告诉别人设备最怕的不是断网而是断网了别人还不知道。比如一个报警器被剪断电源如果没有任何机制通知平台那就等于裸奔。MQTT的遗嘱消息Last Will and TestamentLWT就是用来解决这个问题的。客户端在建立连接时可以同时注册一份遗嘱指定一个Topic和一段Payload。之后如果客户端异常断开网络断了、设备掉电、进程崩溃Broker会检测到连接异常替这个客户端发布遗嘱消息。但要注意如果是客户端主动disconnect()Broker不会发遗嘱因为这属于正常退出。我用一个门窗传感器项目演示过这个机制。设备正常上报时带retain内容类似{state: closed}同时连接时注册遗嘱Topic是device/door/statusPayload是{state: unknown, reason: offline}。这样一来一旦设备掉线任何订阅这个Topic的人都会收到这台设备失联了的通知同时原来的retain消息也会被遗嘱覆盖。这比单纯的心跳超时判断要快得多因为心跳检测需要等好几个KeepAlive周期才能确认超时。6. 安全不能裸奔认证、TLS和正确的Broker配置姿势6.1 裸奔的风险局域网也可能翻车很多人觉得我在局域网里跑MQTT外网连不进来不需要安全措施。这个想法我一开始也有直到有位朋友告诉我他宿舍局域网里一台跑着默认配置Mosquitto的树莓派某天日志里出现了一堆来自同网段陌生IP的连接尝试虽然没有密码进不来但也说明了设备会主动向局域网内广播MQTT服务。更有意思的是现在不少智能家居设备本身就在局域网里用MQTT通信如果你兜底是开放式Broker邻居家一台被入侵的设备可能直接就能往你家的Topic上发消息。退一步讲就算纯本地使用安全配置至少要做两件事禁止匿名访问和设置独立账号。前者堵住无凭证连接后者避免所有设备共用一组万能钥匙。别觉得麻烦这个成本比起事后排查怎么多了那么多陌生流量低得多。6.2 用户密码与ACL权限最小权限原则Mosquitto的安全配置由mosquitto.conf和其他几个文件完成。先看认证部分在配置文件中加allow_anonymous false password_file /etc/mosquitto/passwd然后用mosquitto自带工具生成密码文件sudo mosquitto_passwd -c /etc/mosquitto/passwd sensor_user它会提示输入密码。这里有个小坑修改了配置文件的权限。Mosquitto启动时会检查配置文件的权限太开放的话它可能拒绝启动。设置好之后重启服务sudo systemctl restart mosquitto这时再用mosquitto_pub不带用户名密码去连接会直接报连接被拒绝。比密码更重要的是ACL访问控制列表实现最小权限原则。给客户端分账号时最好像分配系统权限一样思考这个账号只该发布哪些Topic只该订阅哪些Topic。在Mosquitto里用acl_file配置acl_file /etc/mosquitto/aclacl文件的内容类似# sensor_user 只能发布 sensor/ 开头的主题 user sensor_user topic write sensor/# # dashboard_user 只能订阅 sensor/ 和 device/ 开头的主题 user dashboard_user topic read sensor/# topic read device/#这里read和write分别对应订阅和发布权限。注意write不只是控制发布还包括在连接时注册遗嘱主题的权限所以遗嘱Topic也得包含在该账号的可写范围内否则连接会被拒绝。这个细节我踩过一次花了快半小时才从日志里找到原因。6.3 TLS加密链路自签名证书在开发环境的快速启用用户名密码能防住没凭证的人但防不住能抓包的人。同一局域网里用Wireshark一抓MQTT的Payload都是明文传感器数据泄漏还是小事控制指令被人篡改就是安全事件了。所以生产环境必须上TLS。开发环境不想买证书自签名证书就够用。步骤大概是用openssl生成CA证书和服务端证书。在Mosquitto配置里开启8883端口监听并指定证书路径listener 8883 cafile /etc/mosquitto/certs/ca.crt certfile /etc/mosquitto/certs/server.crt keyfile /etc/mosquitto/certs/server.key客户端连接时指定CA证书并开启TLS。用Python的paho-mqtt连接TLS版本时只需在connect()之前调用client.tls_set(ca_certs./ca.crt)注意自签名证书有个坑设备端必须信任这张CA证书把ca.crt拷到设备上手动配置信任否则TLS握手会失败。我用树莓派做测试时一开始漏了这一步一直报SSLError后来才发现是系统的CA证书列表里没加进这张自签CA。7. 踩坑实录连接断开、消息丢失、Topic通配符这些坑我替你踩过了7.1 KeepAlive设太大断线半天才知道KeepAlive机制是MQTT保活的核心它要求客户端在设定的间隔内至少给Broker发一次报文可以是任意报文比如PINGREQ否则Broker认为连接死了帮客户端发布遗嘱。这个参数设多大是个学问。我一开始图省事把keepalive设成了300秒想着5分钟发一次心跳足够了吧。结果在一次弱网测试中设备断了3分钟才恢复而我等了快5分钟才收到遗嘱消息。对于报警系统来说这5分钟可能就是响应黄金时间。后来我把心跳调到了30秒以内配合遗嘱消息能在30到60秒内感知掉线。这里有个经验值KeepAlive建议设为业务允许的掉线感知时间的一半左右比如你希望90秒内发现掉线KeepAlive就设45秒。同时NAT设备家用路由器通常会在几分钟内回收空闲连接KeepAlive太大会导致中间设备的连接被静默回收客户端和Broker还都以为连接活着直到下次发数据才发现断了。7.2 同一Topic重复订阅QoS等级悄悄降级之前说过实际生效的QoS取发布端和订阅端两者的最小值。但还有个更隐蔽的坑同一个客户端多次订阅同一个Topic时后面的订阅会覆盖前面的。比如先用QoS 1订阅了sensor/#又用QoS 0订阅了sensor/room1/temperature那这个客户端收到sensor/room1/temperature消息时实际等级按最后一次订阅的QoS 0来算。这个问题在多账号共享订阅的场景下特别容易出。我之前加了一个公共订阅模块初始化时订阅了一大批Topic后来又在业务代码里单独订阅了其中一个结果这个模块收到的消息全部悄悄降级成了QoS 0丢了几条数据才排查出来。建议是订阅关系统一收敛到一个地方管理不要散落在各个业务模块里。7.3 通配符误用不同需求不同订阅写法通配符的使用也存在理解的偏差。比如我想订阅sensor目录下所有房间的温度直觉写法是sensor//temperature这没问题。但如果写成sensor/#/temperature就错了因为#必须放在Topic的末尾。另一个常见的误用是用#匹配到了不想收的消息比如订阅sensor/#会收到sensor/room1/humidity等所有消息如果你只想处理温度数据就得在on_message里做一层过滤或者在Topic分级设计时就区分清楚。我在一个联动项目里就吃过亏。一个开关设备订阅了command/#本意是接收所有下发指令结果日志里出现了它处理别的设备指令的报错。后来我把指令Topic按设备分成了command/device/{device_id}/#每个设备只订阅自己的前缀问题立刻消失。Topic规范不是你想想就行设计的时候要反复问自己订阅方需要什么粒度发布方会不会误伤数据流向是不是清晰的7.4 数据负载乱用JSON结构化的必要性最后一个坑关乎数据格式。刚开始玩MQTT时有人喜欢直接把数据拼成字符串发出去比如25.5。单个数据看不出问题但消息多了以后订阅端解析就全靠猜这个值是温度还是湿度单位是什么时间戳呢我后来在一个环境监测项目里被迫把已有的几十个Topic统一改成JSON结构为此写了一晚上脚本做迁移教训深刻。现在我的标准做法是Payload统一用JSON并且包含value、unit、timestamp三个基本字段有需要再加device_id、location等。宁可多几个字节也要让消息自我描述。物联网的设备千奇百怪你永远不知道半年后谁会来订阅这个Topic结构化就是给自己和后来者留余地。写在最后一个过来人的体会MQTT这个协议看起来简单五个字母、一个Broker、几条报文但真正用起来才发现它把物联网通信里的很多潜规则都替你想好了弱网下的重连、离线状态的感知、新订阅者的状态同步、权限的精细控制。我这几年接过的设备从温湿度传感器到智能开关、从家庭环境到小规模农场底层通信清一色跑的MQTT中途换过别的方案最后又都换回来了。如果你正在学物联网我的建议是别急着上框架先把Mosquitto跑起来用命令行敲几条消息再用Python写一个最小Demo把上面说的QoS、保留消息、遗嘱消息、安全配置都过一遍。这些概念每个单独拿出来都不难但它们组合在一起就是你以后做任何物联网项目的通信底座。有句话我常跟做设备的朋友说协议选对了后面十年都省心。MQTT对我而言就是这么一个值得花时间打牢基础的协议。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑