Python 客户端脱机时VerneMQ单一发布消息丢失
我对MQTT和代理非常陌生,但我对VerneMQ不向客户端发送脱机消息有一个问题。这是我的设置。我有一个用Python编写的后端,它使用Paho Eclipse MQTT库的single()方法向连接的客户机发送消息。客户机是我开发站上的一个虚拟机,它有一个用go lang编写的客户机,使用paho.mqtt.golang连接到代理并订阅 后端对single()的调用如下所示:Python 客户端脱机时VerneMQ单一发布消息丢失,python,go,mqtt,mqtt-vernemq,Python,Go,Mqtt,Mqtt Vernemq,我对MQTT和代理非常陌生,但我对VerneMQ不向客户端发送脱机消息有一个问题。这是我的设置。我有一个用Python编写的后端,它使用Paho Eclipse MQTT库的single()方法向连接的客户机发送消息。客户机是我开发站上的一个虚拟机,它有一个用go lang编写的客户机,使用paho.mqtt.golang连接到代理并订阅 后端对single()的调用如下所示: def send_message(device_id, payload): token = get_jwt('
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大于0的脱机客户端排队
更多细节可以在评论中找到 消息将仅为订阅的QOS大于0的脱机客户端排队
更多详细信息请参见您需要根据您的需求将QOS设置为1或2,并且您还可以使用非常有用的--retain标志。retain标志将确保不管发生任何故障,最后一条消息都将被传递。您可以知道设备的最后状态。选中此复选框,您需要根据您的需求将QOS设置为1或2,并且您还可以使用非常有用的--retain标志。retain标志将确保不管发生任何故障,最后一条消息都将被传递。您可以知道设备的最后状态。勾选此项您没有包括如何在客户端上订阅此主题QoS仅涵盖1个客户端和代理之间,而不是端到端…只是为了明确我的第一条评论,直到您提出问题以显示您在脱机客户端中订阅此主题时使用的代码,我们无法回答此问题。谢谢,你的评论让我明白了问题所在。我在subscribe方法上指定qos=0。我改为2,现在它开始工作了。你没有包括你如何在客户端上订阅主题QoS只涵盖1个客户端和代理之间,而不是端到端…只是为了真正了解我的第一条评论,直到你提出问题,显示你在离线客户端中订阅主题的代码,我们无法回答。谢谢,你的评论让我明白了问题所在。我在subscribe方法上指定qos=0。我改为2,现在它可以工作了。