通配符
- "+"
单层通配符,可以匹配特定主题层的任何名称
- "#"
多层通配符,可以匹配任何特定主题级别的名称。
例如,如果我们想接收所有无人机的高度相关的消息,我们可以使用+单级通配符代替特定的无人机名称。我们可以使用以下主题过滤器:sensor/+/altitude 。
如果我们将消息发布到以下主题,使用sensor/+/altitude主题过滤器的订阅者将收到所有的消息。
匹配:
sensors/drone01/altitude
sensors/drone02/altitude
sensors/superdrone01/altitude
sensors/thegreatestdrone/altitude
不匹配
sensors/drone01/speed/rotor/1
sensors/superdrone01/speed/rotor/2
sensors/superdrone01/remainingbattery
sensors/drone01/# topic匹配如下:
sensors/drone01/altitude
sensors/drone01/speed/rotor/1
sensors/drone01/speed/rotor/2
sensors/drone01/speed/rotor/3
sensors/drone01/speed/rotor/4
sensors/drone01/remainingbattery
不匹配
sensors/drone02/altitude
sensors/superdrone01/altitude
sensors/thegreatestdrone/altitude
sensors/drone02/speed/rotor/1
sensors/superdrone02/speed/rotor/2
sensors/superdrone02/remainingbattery
QOS
- 0 最多送一次
提供了与底层TCP协议相同的保证。消息不被对方确认。发送方只是将消息发送至目的地,既不存储也不为任何可能无法到达目的地的消息安排新的发送,的开销最低。
- 1 至少一次交付
有确认要求,消息将至少交付给用户一次。它可能会产生重复,发送方会将消息存储起来,直到收到用户的确认。如果发送者在特定时间内没有收到确认,发送者将再次向接收者发布消息。接收者必须有必要的逻辑来检测重复的信息。
- 2 精确的一次交付
消息只交付一次到目的地。QoS级别2的开销最高,要求发送方和接收方之间有两个流。在发送方确定消息已被目的地成功接收一次后,以QoS级别2发布的消息就被认为是成功发送了。
如果发布者使用的QoS级别高于用户指定的QoS级别,那么MQTT服务器在从MQTT服务器向该用户发布消息时,就必须将QoS级别降为特定用户正在使用的最低级别。例如,如果我们使用QoS级别2来发布从发布者到MQTT服务器的消息,但有一个用户在订阅时要求使用QoS级别1,那么从MQTT服务器到该用户的发布将使用QoS级别1。
至少一次交付实例
- 终端1
$ mosquitto_sub -t sensors/+/altitude -q 1 -d
Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending SUBSCRIBE (Mid: 1, Topic: sensors/+/altitude, QoS: 1, Options: 0x00)
Client (null) received SUBACK
Subscribed (mid: 1): 1
Client (null) received PUBLISH (d0, q1, r0, m1, 'sensors/drone02/altitude', ... (4 bytes))
Client (null) sending PUBACK (m1, rc0)
65 f
Client (null) sending PINGREQ
Client (null) received PINGRESP
- 终端2
$ mosquitto_pub -t sensors/drone02/altitude -m "65 f" -q 1 -d
Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending PUBLISH (d0, q1, r0, m1, 'sensors/drone02/altitude', ... (4 bytes))
Client (null) received PUBACK (Mid: 1, RC:0)
Client (null) sending DISCONNECT
下图显示了发布者和MQTT服务器之间的交互,以发布一个QoS级别为1的消息。
MQTT服务器可以在向发布者发送PUBACK包之前,开始向相应的订阅者发布消息。因此,当发布者收到来自MQTT服务器的PUBACK包时,并不意味着所有的订阅者都收到了消息。理解这个PUBACK包的含义是非常重要的。
如果应用能够容忍重复,并且我们必须确保消息至少一次到达用户,那么QoS级别1是一个很好的选择。在没有办法处理重复的情况下,我们必须使用QoS级别2。
准确一次交付实例
- 终端1
$ mosquitto_sub -t sensors/drone03/# -q 2 -d
Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending SUBSCRIBE (Mid: 1, Topic: sensors/drone03/#, QoS: 2, Options: 0x00)
Client (null) received SUBACK
Subscribed (mid: 1): 2
Client (null) received PUBLISH (d0, q2, r0, m1, 'sensors/drone03/speed/rotor/1', ... (5 bytes))
Client (null) sending PUBREC (m1, rc0)
Client (null) received PUBREL (Mid: 1)
Client (null) sending PUBCOMP (m1)
362 f
- 终端2
$ mosquitto_pub -t sensors/drone03/speed/rotor/1 -m "362 f" -q 2 -d
Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending PUBLISH (d0, q2, r0, m1, 'sensors/drone03/speed/rotor/1', ... (5 bytes))
Client (null) received PUBREC (Mid: 1)
Client (null) sending PUBREL (m1)
Client (null) received PUBCOMP (Mid: 1, RC:0)
Client (null) sending DISCONNECT
如果应用程序不能容忍重复,而且我们必须确保消息只到达用户一次,那么QoS级别2是合适的选择。然而,神奇是有代价的:我们必须考虑到,与其他QoS级别相比,QoS级别2的开销最高。