参考手册 https://mcxiaoke.gitbooks.io/mqtt-cn/content/mqtt/01-Introduction.html
MQTT.fx https://www.maxlicheng.com/embedded/iot/337.html
MQTT
简介
基于发布、订阅(publish、subscribe)模式‘轻量级’通讯协议。
优势轻量级,使用极少流量,适合于物联网
协议原理
Qos 实现过程&使用的范围
参考https://blog.csdn.net/zerooffdate/article/details/78950907?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allbaidu_landing_v2~default-6-78950907.nonecase&utm_term=mqtt%20qos2%E8%83%BD%E5%AE%9E%E7%8E%B0%E5%90%97&spm=1000.2123.3001.4430
qos0
qos1
qos2
- 接收者收到publis的QoS2的消息之后,客户端需要保存一个msgid的记录,并且进入一个状态,即之后不管来了几个这个msgid的消息,都不管他,认为是重复的,丢弃。
- 接收到publish的QoS2消息之后,不能马上投递给上层,而是在本地做持久化,将消息保存起来。一个点是这里这里需要是持久化,而不是保存在内存。单纯保存在内存,是不能真正做到QoS2的。
- 收到publish的QoS2消息之后,马上回复一个pubrec给发送端。
- 服务器在收到pubrec之后,应该认为客户端已经收到消息,将publish的消息转入等待 * pubcomp的阶段,不再重发publish,转而下发pubrel
- 客户端收到pubrel之后,正式将消息投递给上层应用层。
- 投递之后,销毁该msgid,返回pubcomp给服务器,销毁之前的持久化消息。
- 之后不管服务器来多少pubrel,都没有messagid的记录,只需要回复pubcomp,不需要投递给上层。
receive release
complete
客户端
- publish
- Subscribe
服务端
- MQTT Broker
客户端通过服务端发布和订阅消息
主要特性
- 使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序的耦合
- 对负载内容屏蔽消息传输
- 使用tcp/ip提供网络连接
三种消息发布模式服务质量Qos
- 至多一次
- 至少一次
- 只有一次
小型传输,开销很小(固定长度的头部长度为2字节),协议交换最小化,以降低网络流量
传输消息
主题Topic
- 可以理解消息类型,订阅者订阅后就会收到相关的内容
负载payload
- 消息的内容,指订阅者具体要使用的内容
协议包结构
固定头fixed header
- 表示数据包类型及数据包组织标识
可变头variable header
- 由固定头包类型决定是否存在可变头,及其内容
消息体payload
- 具体消息内容
代理服务器功能broker
- 可以支持几千的客户端并发连接
- 主要职责是接受所有消息,并将其过滤后分发给不同消息订阅者
- 可以根据订阅内容和未送达的消息来保持持久的会话
- 另一个职责是验证和授权客户端
- 只是一个网络通信的组件
- 是一个中心交换机,交换所有的数据
代理服务器功能名词
- QoS 0:服务质量 0,最多传输一次。
- QoS 1:服务质量1,至少传输一次。
- QoS 2:服务质量2,仅仅传输一次。
- auth:验证,身份验证授权。
- bridge:桥接,服务器代理之间连接
- $SYS:主题过滤器通配符,订阅后能够接收到所有以此通配符开头的主题的消息。
- dynamic topics:动态主题
- cluster:集群
emqttd
apache activeMQ
在物联网中使用mqtt协议是工作在低带宽、不可靠的网络远程传感器和控制设备通讯而设计的协议。
1.它使用了发布/订阅的模式,提供一对多的发布消息。
2.对负载内容屏蔽的消息传输。
3.使用TCP/IP提供网络连接。
4.有三种消息发布质量:
- “至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
- “至少一次”,确保消息到达,但消息重复可能会发生。
“只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
在系统设计中有以下几种情景:
- 某个app发送消息给某一台主机(比如发送设备请求)
- 某台主机发送消息给某个app(比如设备控制的应答)
- 某台主机发送消息给所有登录这么主机的app(比如更新设备状态 )
为了应对以上三种情况,每个设备都订阅自己的ID+REC的主题,当前设备需要向对方发送消息时就发布对方ID+REC的主题的消息,这样就满足前两种情况。比如用户ID是 13312345678,则订阅主题为“topic/13312345678REC”的消息,当用户需要向主机发送消息的时候,可以通过Mqtt服务器发面主题为“topic/M0011024549REC”的消息。反过来如果主机需要单独向此用户发送消息,则可以发布主题为“topic/13312345678REC”的消息。 对于第三种情况,需要app再单独订阅一个当前用户登录的主机的群发消息,这个消息的主题是为对应主机的ID+BROADCAST,也就是说用户app在登录到某个主机以后,除了订阅自己的ID+REC外,还应该再订阅一个登录主机ID+BROADCAST的主题,比如上面的例子,用户13312345678在登录到M0011024549主机以后还需要再订阅一个“topic/M0011024549BROADCAST”的主题,主机M0011024549在需要向所有登录到该主机的用户发布消息时直接发布主休为"topic/M0011024549BROADCAST"的消息即可,所有登录的用户都可以收到。
设备做成一个mqtt客户端-发布topic----后台mqtt服务器接收数据------后台系统展示mqtt客户端订阅展示
嵌入式板子消息体使用json还是字节码传输消息?
参考https://www.cnblogs.com/xueweisuoyong/p/11171804.html
- 那么单片机的开发中,处理JSON数据虽然有现成的函数库可用,但是对硬件要求就提高了不少,成本自然就上升了。还有处理速度也没有短指令那么快,虽然单片机提高了一个档次,但是因为要处理JSON数据,接收和发送指令时的速度并没有得到显著提升
- 想要提高物联网连接服务器性能,尽可能加大单台服务器的接入量(短指令代替JSON数据包的思路进行开发,对服务器承载能力扩大不只几倍,优化好会提升10几倍甚至更高),那么使用短指令是个必要的选择,再配以相适应的开发方法,会是物联网项目整体性能大幅提升。
mqtt 中retained消息
Retain 消息有以下一些特点:
一个 Topic 只能有 1 条 Retained 消息,发布新的 Retained 消息将覆盖老的 Retained 消息;
如果订阅者使用通配符订阅主题,它会收到所有匹配的主题上的 Retained 消息;
只有新的订阅者才会收到 Retained 消息,如果订阅者重复订阅一个主题,也会被当做新的订阅者,然后收到 Retained 消息;
Retained 消息发送到订阅者时,消息的 Retain 标识仍然是 1,订阅者可以判断这个消息是否是 Retained 消息,以做相应的处理。
注意:Retained 消息和持久性会话没有任何关系,Retained 消息是 Broker 为每一个 Topic 单独存储的,而持久性会话是 Broker 为每一个 Client 单独存储的。
如果你想删除一个 Retained 消息也很简单,只要向这个主题发布一个 Payload 长度为 0 的 Retained 消息就可以了。
https://blog.csdn.net/z69183787/article/details/108899618