如何在eclipse-mosquitto中使用QoS MQTT接收脱机客户端的消息?

问题描述 投票:0回答:2

我的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代理发送已存储的消息

实际发生的事情

无限期等待消息

也许我缺少什么?

mqtt mosquitto
2个回答
2
投票
我认为mqtt spec的相关位是:

[当服务器取得传入应用程序消息的所有权时,必须将其添加到具有匹配条件的那些客户端的会话状态中订阅。

在您发布消息的情况下,没有匹配订阅的客户端(因为此时您还没有运行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配置中还有一些选项可让您限制消息的数量举行和举行多久。


1
投票
MQTT不能那样工作。

消息仅对以前已连接的客户端排队,它是发布/订阅系统,而不是消息队列系统。

一个客户过去必须已连接,并已将相关消息订阅到该主题。然后,在将cleanSession标志设置为false并使用相同的客户端ID发布消息之后,需要重新连接。

您可以在HiveMQ博客here上了解有关此内容的更多信息>

© www.soinside.com 2019 - 2024. All rights reserved.