Go MOSQUITO用户接收额外消息

Go MOSQUITO用户接收额外消息,go,mqtt,mosquitto,Go,Mqtt,Mosquitto,作为一个完全的初学者,我正在探索莫斯奎托。我有一个golang测试程序,我正在使用它来查看它是如何管理消息的,但该程序的后续运行会显示收到的额外消息 import ( mqtt "github.com/eclipse/paho.mqtt.golang" log "github.com/sirupsen/logrus" "strconv" "time" ) var sent int va

作为一个完全的初学者,我正在探索莫斯奎托。我有一个golang测试程序,我正在使用它来查看它是如何管理消息的,但该程序的后续运行会显示收到的额外消息

import (
    mqtt "github.com/eclipse/paho.mqtt.golang"
    log "github.com/sirupsen/logrus"
    "strconv"
    "time"
)
var sent int
var received int

func Test() {
    sent  = 0
    received = 0
    const TOPIC = "mytopic/test"

    opts := mqtt.NewClientOptions().AddBroker("tcp://localhost:1883").SetClientID("client1").SetResumeSubs(false).SetAutoReconnect(false).SetCleanSession(true)

    client1 := mqtt.NewClient(opts)
    if token := client1.Connect(); token.Wait() && token.Error() != nil {
        panic(token.Error())
    }
    if token := client1.Subscribe(TOPIC, 2, receiver1); token.Wait() && token.Error() != nil {
        panic(token.Error())
    }

    defer howManySent()
    defer howManyReceived()
    defer client1.Disconnect(1)

    for index:=0;index<3;index++ {
        sendMsg := "client1 message " + strconv.Itoa(index)
        if token := client1.Publish(TOPIC, 2, true, sendMsg); token.Wait() && token.Error() != nil {
            panic(token.Error())
        } else {
            sent++
        }
        time.Sleep(1 * time.Second)
    }
    time.Sleep(1*time.Second)
}

func howManyReceived() {
    log.Warn("RECEIVED:", received)
}

func howManySent() {
    log.Warn("SENT:", sent)
}

func receiver1(client mqtt.Client, msg mqtt.Message) {
    received++
    msg.Ack()
    output := "message id:" + strconv.Itoa(int(msg.MessageID())) + " message = " + string(msg.Payload())
    log.Warn(output)
}
第二次运行的输出:

WARN[0000] message id:4 message = client1 message 2     
WARN[0000] message id:5 message = client1 message 0     
WARN[0001] message id:6 message = client1 message 1     
WARN[0002] message id:7 message = client1 message 2     
WARN[0004] RECEIVED:4                                   
WARN[0004] SENT:3    
我的配置文件是MOSQUITO默认安装的配置文件,只是我关闭了持久性以查看它是否有帮助:

# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example

pid_file /var/run/mosquitto.pid

persistence false
persistence_location /var/lib/mosquitto/

log_dest file /var/log/mosquitto/mosquitto.log

include_dir /etc/mosquitto/conf.d
我做错了什么?

的定义如下:

Publish(topic string, qos byte, retained bool, payload interface{}) Token
因此,当您调用
token:=client1.Publish(TOPIC,2,true,sendMsg)
时,您正在发布一条
retained
设置为true的消息。是消息传递给代理的标志,表示:

如果RETAIN标志设置为1,则在客户端发送到服务器的发布数据包中,服务器必须存储应用程序消息及其QoS,以便将其发送给订阅与其主题名称匹配的未来订户[MQTT-3.3.1-5]。建立新订阅时,必须将每个匹配主题名称上的最后保留消息(如果有)发送给订阅服务器[MQTT-3.3.1-6]

设置了
retain
的每一条新消息都将替换以前的任何消息,因此当您的第一次执行完成时,消息
2
将被保留。这将在客户端重新连接时发送到客户端(意味着您看到的结果是预期的)。如果将调用更改为
token:=client1.Publish(TOPIC,2,false,sendMsg)
它将按照您的预期运行

下面是关于
持久性
标志的说明:

如果为true,则连接、订阅和消息数据将写入mosquito.db中由持久性位置指定的位置的磁盘。重新启动mosquitcho时,它将重新加载存储在mosquitcho.db中的信息


因此,这只有在重新启动Mosquitto时才会产生影响;即使此标志设置为
false

但消息已传递并确认,会话信息仍将存储在内存中。为什么要存储它?假设我已将持久性配置为false,并已验证不存在mosquito.db文件。。。更奇怪的是,它存储在哪里我猜它存储在内存中了?但我尝试重新启动服务器,得到了相同的结果。另外,如果我使用相同的客户端ID,这会被视为新订阅吗?它存储在内存中。如果在
mosquitto.conf
中出现
persistence false
,则在重新启动mosquitto后首次运行应用程序时,不应收到额外消息。参考
相同的客户ID
;您正在使用
SetCleanSession(true)
,它告诉代理在断开连接时丢弃客户端会话。在任何情况下,都要求发送保留的消息,即使已经存在相同的订阅。
Publish(topic string, qos byte, retained bool, payload interface{}) Token