【问题标题】:VerneMQ single publish messages lost when client is offlineVerneMQ 单次发布消息在客户端离线时丢失
【发布时间】:2020-11-18 04:28:27
【问题描述】:

我对 MQTT 和代理很陌生,但我遇到了 VerneMQ 不向客户端发送离线消息的问题。这是我的设置。我有一个用 Python 编写的后端,它使用 Paho Eclipse MQTT 库的 single() 方法将消息发送到连接的客户端。客户端,我开发站上的一个虚拟机,有一个用go-lang编写的客户端,使用paho.mqtt.golang连接broker并订阅。

后端对 single() 的调用如下所示:

def send_message(device_id, payload):
    token = get_jwt('my_token').decode()
    mqtt.single(
       f'commands/{device_id}',
       payload=payload,
       qos=2,
       hostname=MESSAGING_HOST,
       port=8080,
       client_id='client_id',
       auth={'username': 'username', 'password': f'Bearer {token}'},
       transport='websockets'
   )

在客户端上,使用以下选项建立会话:

func startListenerRun(cmd *cobra.Command, args []string) {
//mqtt.DEBUG = log.New(os.Stdout, "", 0)
mqtt.ERROR = log.New(os.Stdout, "", 0)
opts := mqtt.NewClientOptions().AddBroker(utils.GetMessagingHost()).SetClientID(utils.GetClientId())
opts.SetKeepAlive(20 * time.Second)
opts.SetDefaultPublishHandler(f)
opts.SetPingTimeout(5 * time.Second)
opts.SetCredentialsProvider(credentialsProvider)
opts.SetConnectRetry(false)
opts.SetAutoReconnect(true)
opts.willQos=2
opts.SetCleanSession(false)

我没有展示所有代码,但希望足以说明会话是如何设置的。

我将 VerneMQ 作为 docker 容器运行。我们正在使用以下环境变量来更改 Dockerfile 中的配置默认值:

ENV DOCKER_VERNEMQ_PLUGINS.vmq_diversity on
ENV DOCKER_VERNEMQ_VMQ_DIVERSITY.myscript1.file /etc/vernemq/authentication.lua
ENV DOCKER_VERNEMQ_VMQ_ACL.acl_file /etc/vernemq/vmq.acl
ENV DOCKER_VERNEMQ_PLUGINS.vmq_acl on
ENV DOCKER_VERNEMQ_RETRY_INTERVAL=3000

只要客户端与代理有活动连接,服务器发布的消息就会无缝到达。但是,如果我手动关闭客户端与代理的​​连接,然后在后端向该客户端发布消息,则当客户端的连接重新打开时,代理不会重新发送消息。正如我所说,我是 MQTT 的新手,所以我可能需要配置其他选项,但到目前为止我还没有确定哪个。任何人都可以阐明我的设置中可能发生的会导致无法发送离线消息的情况吗?感谢您提供任何信息。

【问题讨论】:

  • 你没有包括你在客户端订阅主题的方式
  • QOS 仅涵盖 1 个客户端和代理之间,而不是端到端...
  • 只是为了真正清楚我的第一条评论,直到您 edit 显示您用于在离线客户端中订阅该主题的代码的问题,我们无法回答这个问题。
  • 谢谢,您的评论向我展示了这个问题。我在 subscribe 方法上指定了 qos =0 。我改为 2,现在它正在工作。

标签: python go mqtt mqtt-vernemq


【解决方案1】:

在 cmets 中被淘汰

消息只会为订阅超过 QOS 0 的离线客户端排队

更多详情可以查看here

【讨论】:

    【解决方案2】:

    您需要根据您的要求将 QOS 设置为 1 或 2,您还可以使用 --retain 标志,这非常有用。保留标志将确保无论任何失败都将传递最后一条消息。您可以知道设备的最后状态。检查这个http://www.steves-internet-guide.com/mqtt-retained-messages-example/

    【讨论】:

      猜你喜欢
      • 2021-08-31
      • 1970-01-01
      • 2015-08-17
      • 2019-02-20
      • 1970-01-01
      • 1970-01-01
      • 2015-07-21
      • 2014-12-26
      • 1970-01-01
      相关资源
      最近更新 更多