我对MQTT和代理还很陌生,但VerneMQ不向客户端发送脱机消息时遇到了问题。这是我的设置。我有一个用Python编写的后端,它使用Paho Eclipse MQTT库的single((方法向连接的客户端发送消息。客户端是我的开发站上的一个虚拟机,它有一个用go lang编写的客户端,使用paho.mqtt.golang连接到代理并订阅。
后端对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作为一个码头集装箱。我们使用以下环境变量来更改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设置为1或2,还可以使用--retain标志,这非常有用。retain标志将确保最后一条消息将被传递,而不考虑任何失败。您可以知道设备的最后状态。检查这个http://www.steves-internet-guide.com/mqtt-retained-messages-example/