一旦接收到Spring MQTT集成,如何停止对保留消息的重复订阅

时间:2019-04-04 07:46:01

标签: java spring spring-integration mqtt mosquitto

订阅保留的主题时获得重复的保留消息。

我在Iot项目中使用spring mqtt集成。 在这里,一旦收到保留的消息,它将继续进行订阅,直到我将保留标志设置为true的空白消息发布到同一主题为止。 我已经注意到,当我在终端中使用mqtt命令执行相同的过程,以便订阅保留的主题时,该订阅仅订阅一次,因此不会重复订阅。

我使用以下代码使用#

订阅了所有主题
@Bean
    public MessageChannel mqttInputChannel() {
        return new DirectChannel();
    }
    @Bean
    public DefaultMqttPahoClientFactory clientfactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        MqttConnectOptions options = new MqttConnectOptions();
        options.setUserName("username");
        options.setPassword("password".toCharArray());
        options.setCleanSession(false);
        //options.setCleanSession(true);
        //options.setServerURIs(new String[] { "tcp://localhost" });
        options.setServerURIs(new String[] { "url" });
        factory.setConnectionOptions(options);
        return factory;
    }

    @Bean
    public MqttPahoMessageDrivenChannelAdapter inbound() {

        MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter("admin",
                clientfactory(), "#");
        adapter.setConverter(new DefaultPahoMessageConverter());
        adapter.setQos(1);
        adapter.setOutputChannel(mqttInputChannel());
        /*adapter.setc*/
        return adapter;
    }

    @Bean
    @ServiceActivator(inputChannel = "mqttInputChannel")

    public MessageHandler handler() {
        return new MessageHandler() {

            public void handleMessage(Message<?> message) throws MessagingException {

            mqttSubscriptionProcessor.processSubscription(message);


            }

        };
    }

我使用此命令发布了保留的消息

mosquitto_pub -u admin -P pwd -t hello/topic  -m "test msg" -r -d

并且在eclipse控制台中的结果是

{mqtt_receivedRetained=true, id=48afaec5-debf-4927-ce06-a80556e479ac, mqtt_duplicate=false, mqtt_receivedTopic=hello/topic, mqtt_receivedQos=0, timestamp=1554363853214}
test msg

{mqtt_receivedRetained=true, id=48afaec5-debf-4927-ce06-a80556e479ac, mqtt_duplicate=false, mqtt_receivedTopic=hello/topic, mqtt_receivedQos=0, timestamp=1554363853214}
test msg

{mqtt_receivedRetained=true, id=48afaec5-debf-4927-ce06-a80556e479ac, mqtt_duplicate=false, mqtt_receivedTopic=hello/topic, mqtt_receivedQos=0, timestamp=1554363853214}
test msg 

{mqtt_receivedRetained=true, id=48afaec5-debf-4927-ce06-a80556e479ac, mqtt_duplicate=false, mqtt_receivedTopic=hello/topic, mqtt_receivedQos=0, timestamp=1554363853214}
test msg

在这里,我只需要预订一次保留的主题,就必须更改spring集成代码中的所有更改。

1 个答案:

答案 0 :(得分:1)

这是保留消息的工作方式,将保留位设置为主题的最后发布的消息总是在它们订阅任何新消息之前,先订阅给匹配的主题的客户端。

如果您不希望保留邮件(因此总是发送邮件),那么在发布时不要设置保留位。

否则,您会发现发布有效载荷为空且保留位设置为同一主题的消息,从而可以清除该主题的保留消息。

或者您可以过滤客户端中的消息,因为您始终可以检查传递邮件时是否在邮件上设置了保留标志。

至于春季,您似乎正在创建4个客户端,因此每个客户端在订阅时都会收到消息。您可以通过查看代理日志来证明这一点,如果您以详细模式运行mosquitto,它将显示它传递的每条消息。