我的mosquitto.conf是(这是整个conf文件,因为其他所有内容都已被注释掉)
log_dest file /mosquitto/log/mosquitto.log
log_type all
connection_messages true
log_timestamp true
log_timestamp_format [%H:%M:%S]
persistence true
persistence_location /mosquitto/data/
listener 1883
listener 9001
protocol websockets
然后我跑步
docker exec -it ecs-Eclipse_mosquitto_MQTT-11-Eclipse-mosquitto-MQTT-eafxxxxxxx mosquitto_pub -t presence -m hellothere -q qos=2
(NOTE我还没有任何在线有效订阅者]
定位到/mosquitto/data
,确实有一个名为mosquitto.db
的文件
所以我可以推断出我的消息hellothere
存储在mosquitto.db
中
然后我执行了命令
docker exec -it ecs-Eclipse_mosquitto_MQTT-11-Eclipse-mosquitto-MQTT-eafxxxxxxx mosquitto_sub -t presence -q qos=2
我期望什么
由于订阅者现在处于在线状态,因此MQTT代理发送已存储的消息
实际发生的事情
无限期等待消息
也许我缺少什么?
[当服务器取得传入应用程序消息的所有权时,必须将其添加到具有匹配条件的那些客户端的会话状态中订阅。
在您发布消息的情况下,没有匹配订阅的客户端(因为此时您还没有运行mosquitto_sub
),因此它不会进一步执行任何操作。
如果要为客户端存储消息,则必须首先作为该客户端连接,并订阅相关主题(使用QOS> 0和CleanSession = 0)。完成此操作后,客户端脱机时收到的所有消息都将在重新连接时进行存储和传递(只要CleanSession = 0)。
注意:要对mosquitto_sub
执行上述操作,您将需要使用--id
参数来设置客户端ID(消息只会针对已订阅相关主题的特定客户端排队)。您还需要-c
标志来禁用“干净会话”标志。
因此步骤如下(我已删除了多余的docker位-您可以重新添加这些位:]
mosquitto_sub -c --id subscriber1 -t presence -q 2
这将订阅,然后等待任何消息;您可以安全地关闭它(这是需要发生的订阅位)。接下来发布您的信息:
mosquitto_pub -t presence -m hellothere -q 2
现在您可以再次启动mosquitto_sub
以检索存储的消息:
mosquitto_sub -c --id subscriber1 -t presence -q 2
警告:当您像这样订阅时,代理将存储您离线时收到的所有消息。如果您正在测试处理大量消息的代理,这可能会成为问题(因为存储所有消息会占用空间)。此处可能不是问题,因为您仅进行测试,但要记住一点...在没有mosquitto_sub
的情况下运行-c
将清除所有订阅-mosquitto配置中还有一些选项可让您限制消息的数量举行和举行多久。
消息仅对以前已连接的客户端排队,它是发布/订阅系统,而不是消息队列系统。
一个客户过去必须已连接,并已将相关消息订阅到该主题。然后,在将cleanSession标志设置为false并使用相同的客户端ID发布消息之后,需要重新连接。
您可以在HiveMQ博客here上了解有关此内容的更多信息>