使用Paho Client在Moquette中不会使用脱机消息

时间:2018-03-07 11:46:23

标签: java mqtt paho moquette

我在通过eclipse Paho客户端在Moquette服务器中使用脱机MQTT消息时遇到了问题。

以下是我遵循的步骤。

  1. 创建并调整了Moquette MQTT经纪人。
  2. 使用eclipse Paho客户端创建了一个简单的MQTT使用者应用程序。
  3. 将消费者设置为使用主题数据:" devices / reported /#"使用QOS:1和CleanSession:False
  4. 创建了一个简单的MQTT数据发布者,使用Eclipse Paho将数据发布到MQTT代理。
  5. 使用MQTT数据发布者将消息发布到:" devices / reported / client_1" QOS主题:1
  6. 上述步骤成功,没有任何问题。

    然后我停止了我的消费者应用程序并将MQTT数据发送到具有相同主题的代理。使用我的发布者应用程序 - 服务器能够接收这些消息,但在这一刻,没有任何消费者使用此消息,因为我已经停止了我的消费者。 然后我又开始了我的消费者申请。它已成功连接到代理,但它没有收到我在消费者关闭时发送给代理的任何消息。

    我是否需要对我的Moquette服务器进行任何特定配置以保留数据(使用clean session:false)? 或者我错过了什么?

    请在下面找到我的示例代码,

    Moquette服务器初始化

    if message.content.startswith("!unassign"):
        roles_cleared = True
    
        for r in role_list:
            # Check every role
            role = discord.utils.get(message.server.roles, name=r)
            if role in message.author.roles:
                # If they have the role, get rid of it
                try:
                    await client.remove_roles(message.author, role)
                    await asyncio.sleep(1)
                except discord.Forbidden:
                    await client.send_message(message.author, "I don't have perms to remove roles.")
                    roles_cleared = False
                    break
    
        if roles_cleared:
            await client.send_message(message.author, "Roles successfully cleared.")
    

    MQTT消费者

    package com.gbids.mqtt.moquette.main;
    
    import com.gbids.mqtt.moquette.server.PublishInterceptor;
    import io.moquette.interception.InterceptHandler;
    import io.moquette.server.Server;
    import io.moquette.server.config.IConfig;
    import io.moquette.server.config.MemoryConfig;
    
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Properties;
    
    public class ServerLauncher {
    
        public static void main(String[] args) throws IOException {
            Properties props = new Properties();
            final IConfig configs = new MemoryConfig(props);
    
            final Server mqttBroker = new Server();
            final List<? extends InterceptHandler> userHandlers = Arrays.asList(new PublishInterceptor());
            mqttBroker.startServer(configs, userHandlers);
    
            System.out.println("moquette mqtt broker started, press ctrl-c to shutdown..");
            Runtime.getRuntime().addShutdownHook(new Thread() {
                @Override
                public void run() {
                    System.out.println("stopping moquette mqtt broker..");
                    mqttBroker.stopServer();
                    System.out.println("moquette mqtt broker stopped");
                }
            });
        }
    }
    

    MQTT Publisher

    package com.gbids.mqtt.moquette.main;
    
    import org.eclipse.paho.client.mqttv3.*;
    import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
    
    public class ConsumerLauncher implements MqttCallback {
    
        private static final String topicPrefix = "devices/reported";
        private static final String broker = "tcp://0.0.0.0:1883";
        private static final String clientIdPrefix = "consumer";
    
        public static void main(String[] args) throws MqttException {
            final String clientId = "consumer_1";
            MqttClient sampleClient = new MqttClient(broker, clientId, new MemoryPersistence());
            MqttConnectOptions connOpts = new MqttConnectOptions();
            connOpts.setCleanSession(false);
            sampleClient.connect(connOpts);
            sampleClient.subscribe(topicPrefix + "/#", 1);
            sampleClient.setCallback(new ConsumerLauncher());
        }
    
        public void connectionLost(Throwable throwable) {
            System.out.println("Consumer connection lost : " + throwable.getMessage());
        }
    
        public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
            System.out.println("Message arrived from topic : " + s + " | Message : " + new String(mqttMessage.getPayload()) + " | Message ID : " +mqttMessage.getId());
        }
    
        public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
            System.out.println("Delivery completed from : " + clientIdPrefix + "_1");
        }
    }
    

1 个答案:

答案 0 :(得分:0)

在您的情况下,在retained(发布商)中创建true时,您需要将MqttMessage标记设置为ClientLauncher。默认值为false,如documentation

...    
message.setRetained(true)
...

设置此标志可以使消息保留在代理上并发送到新连接的客户端。请注意,代理只保留主题的最后一条消息。没有办法为特定主题保留多条消息。