4 操作行为
4.1 存储状态
Session 代表客户端和服务端的消息是否需要保留,但是 “保留消息”(功能)并不受到Session的影响
如果服务端和客户端的通信保存着Session,那么客户端离线,服务端会保留他需要接受的消息。在客户端下次
上线的时候,将消息发送给客户端。
4.2 网络连接
底层只要提供有序可靠的连接就行,不局限TCP/IP(只不过MQTT3.1使用)。TLS [RFC5246]、WebSocket [RFC6455]
4.3 消息质量
客户端发送订阅消息需要规定消息质量QoS:
1.QoS 0: 最多分发一次(过程如下)
1.客户端发送消息到服务端。(不管服务端有没有收到)
发送者 | 方向 | 接收者 |
---|---|---|
PUBLISH报文 Qos=0 DUP=0 | —————————-> | 分发应用消息给适当的后续接收者 |
2.QoS 1:最少一次到达(过程如下)
- 客户端发送消息到服务端
- 服务端接受到消息,并发送给订阅者,同时回复客户端
- 客户端收到服务端的回复,停止发送。否则客户端再次发送消息(过程1)。
发送者 | 方向 | 接收者 |
---|---|---|
PUBLISH报文 QoS=1, DUP=0 报文标识符 | —————————-> | 分发消息 |
丢弃消息,结束通讯 | <—————————- | PUBACK报文,带报文标识符 |
3.QoS 2 只有一次到达(过程如下)
- 客户端发送消息(messageID)到服务端
- 服务端接受到消息,保存消息,同时回复客户端接收到消息(messageID)
- 客户端接收到服务端的确认消息,客户端再次发送消息到服务端(messageID),否则(执行过程1)
- 服务端接收到消息之后,下发消息,并将消息删除,同时回复客户端
- 客户端接收到回复标识消息传输完成。否则客户端继续发送消息给服务端(过程3)
发送者 | 方向 | 接收者 | |
---|---|---|---|
1 | 发送PUBLISH报文,带报文标识符 | —————————-> | 存储消息 |
2 | 存储PUBREC中的报文标识符 | <—————————- | 发送PUBREC报文,带报文标识符 |
3 | 发送PUBREL报文,带报文标识符 | —————————-> | 分发消息并丢弃 |
4 | 丢弃已保存的报文标识符,结束通讯 | <—————————- | 发送PUBCOMP报文,带报文标识符 |
:假如过程2客户端没有接收到服务端的确认消息,客户端会重新执行过程1,直到客户端接收到服务端的确认消息,会导致服务端存储着客户端多次发生的数据。但是当客户端接收到消息执行过程3时,会通过messageId通知服务端发送固定的消息。
:假如过程4客户端没有接收到服务端的消息发送通知,会重新执行过程3,由于服务端第一次接受的时候,已将消息分发,并且丢弃,不会多次分发。
4.4 消息传输
重传
客户端掉线之后的重连,不会重发之前没有发送完的消息。不论”Session”是否被清空。
接收
客户端只要接收到了来自服务端的消息,都需要按照服务质量”QoS”的规则来进行回复。
发送
客户端发送消息的顺序需要按照接收到的消息顺序。必须默认把每个话题都当作”有序话题”。
4.5 主题格式
客户端与服务端通讯需要订阅相应的主题。而主题的格式与正则表达式一样有相应的规则:
层级划分 ‘/‘
主题之间通过 ‘/‘来代表层级。例:sport/tennis,父级sport,子级tennis。
通配符 ‘/#’
订阅 | 匹配 |
---|---|
sport/tennis/player1/# | sport/tennis/player1 |
sport/tennis/player1/test1 | |
sport/tennis/player1/test1/test2 |
单层级通配符 ‘/+’
订阅 | 匹配 |
---|---|
sport/tennis/player1/+ | sport/tennis/player1/ |
sport/tennis/player1/test1 |
系统主题’$’
以’$’开头的主题,不受以上规则的约束。类似服务端自定义主题,用户可以自定义以’$’开头的主题,来完成相应 的功能,来供客户端使用。 例:$SYS/ 地被用作包含服务端特别信息的主题前缀。
主题格式
- 长度:主题最大65535个字节
- 编码:UTF-8
- 区分大小写,可包含空格
5 安全认证
MQTT是传输协议,传输的数据为明文,安全性低。而安全特性是实现者的责任。
5.1 MQTT的传输层主要问题:
- 客户端和服务端的静态数据容易被访问到
- 通信可能被拦截,篡改,重定向,泄漏
1 传输的数据被其他人获取(解决方法如下)
- <font style="color:#50596C;">客户端传输的数据可以自行加密</font>
- <font style="color:#50596C;">可以在服务端添加CA证书认证</font>
2 客户端泄漏,其他人模拟数据发送(解决方法如下)
- 判断数据传输的ip与真正的客户ip是否相同
5.2 检测反常行为
我们可以通过一些检查,来判断当前客户端是否有异常
- 重复连接 、认证 、订阅
- 试图发送或订阅太多话题
- 发送无法投递的消息,没有人订阅这个话题