使用持久性将 mosquitto MQTT 代理发送到亚马逊物联网服务的重复消息

Repeated messages mosquitto MQTT broker to amazon IoT Service using persistence

我有一个带有 mosquitto 代理的 Raspberry,并与亚马逊物联网服务桥接。 https://aws.amazon.com/es/blogs/iot/how-to-bridge-mosquitto-mqtt-broker-to-aws-iot/

这是我的 mosquitto.conf 文件:

# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example

pid_file /var/run/mosquitto.pid

persistence true
persistence_location /var/lib/mosquitto/

log_dest file /var/log/mosquitto/mosquitto.log

include_dir /etc/mosquitto/conf.d

这是 /etc/mosquitto/conf.d

里面的 bridge.conf
# =================================================================
# Bridges to AWS IOT
# =================================================================

# AWS IoT endpoint, use AWS CLI 'aws iot describe-endpoint'
connection awsiot
address xxxxxxxxx.iot.eu-central-1.amazonaws.com:8883

# Specifying which topics are bridged
topic awsiot_to_localgateway in 1
topic localgateway_to_awsiot/iot out 1
topic both_directions both 1

# Setting protocol version explicitly
bridge_protocol_version mqttv311
bridge_insecure false

# Bridge connection name and MQTT client Id,
# enabling the connection automatically when the broker starts.
cleansession true
clientid bridgeawsiot
start_type automatic
notifications false
log_type all

# =================================================================
# Certificate based SSL/TLS support
# -----------------------------------------------------------------
#Path to the rootCA
bridge_cafile /etc/mosquitto/certs/rootCA.pem

# Path to the PEM encoded client certificate
bridge_certfile /etc/mosquitto/certs/cert.crt

# Path to the PEM encoded client private key
bridge_keyfile /etc/mosquitto/certs/private.key

一切正常。但是,如果我拔下以太网电缆来测试持久性。当通信重新建立时。代理向亚马逊物联网服务发送重复消息。

这是我要发送的消息

char dataToSend[] = "Message Id: ";
counter++;

snprintf(dataToSend, sizeof(dataToSend) + 10, "Message Id: %d", counter);
app_mqtt_publish(&dataToSend);

这是正常行为吗?

MQTT 规范(部分)的简短版本:

  • QOS 0 -> 可以传送消息
  • QOS 1 -> 消息将至少传送一次
  • QOS 2 -> 消息将被传递一次且仅传递一次。

因此,如果消息未被确认,则 QOS 1 消息可能会再次传送。他们应该在 header 中设置 DUP 标志,以便接收经纪人应该知道他们可能已经交付。

IIRC AWS-IoT 不支持 QOS 2,因此您可能已经忍受了。

AWS IoT 不支持 cleansession false。桥梁的结果是,当:

  • 您发送消息时出错
  • 并且有 persistence true
  • 并没有有效地断开连接
  • 并且 QoS > 0 甚至 QoS = 0 if queue_qos0_messages true

=> 消息保存在数据库中。

但是如果客户端自动设置为桥有效断开连接,cleansession true 告诉代理不要持久化数据,因此它会清除此客户端的数据库。

希望 AWS IoT 在您发送 cleansession false 时没有断开连接,这样我们就可以保留这个本地缓存...

ps:"client automatically set to the bridge"是指,当你在两个broker之间设置一个bridge时,会创建一个客户端来订阅一个并总是发布到另一个。