0
votes

I am implementing MQTT Client with Eclipse Paho and has some problems:

Both Publisher and Subscriber connect to broker with qos = 1 and setCleanSession = false.

My flow:

  1. Connect Subscriber and Publisher to broker, it's ok.
  2. Disconnect Subscriber (I force stop My Project which include Subscriber ), Publisher continuing publishing message.
  3. Reconnect Subscriber -> it cannot connect and throw exception: connectionLost.

If i set qos of Subscriber = 0, it not throw exception but The client does not receive messages sent by the publisher while the subscriber is offline, which I do not want

Can someone help me with this?


This is my code in subcriber

try {
            // Create an Mqtt client
            MqttAsyncClient mqttClient
                    = new MqttAsyncClient("tcp://" + swmConfig.getMqttApiLink(), "MeasureTransactionApi");
            // new MqttAsyncClient(serverURI, clientId, persistence)
            MqttConnectOptions connOpts = new MqttConnectOptions();
            connOpts.setUserName(swmConfig.getMqttUsername());
            connOpts.setPassword(swmConfig.getMqttPassword().toCharArray());
            connOpts.setCleanSession(false);

            // Connect to RabbitMQ Broker
            log.info("Connecting to RabbitMQ broker: " + swmConfig.getMqttApiLink());
            IMqttToken conToken = mqttClient.connect(connOpts);
            conToken.waitForCompletion(10000);
            if (!conToken.isComplete() || conToken.getException() != null) {
                log.info("Error connecting: " + conToken.getException());
                System.exit(-1);
            }
            log.info("Connected");

            // Latch used for synchronizing b/w threads
            final CountDownLatch latch = new CountDownLatch(1);

            // Callback - Anonymous inner-class for receiving messages
            mqttClient.setCallback(new MqttCallback() {

                public void messageArrived(String topic, MqttMessage message) {
                    String time = new Timestamp(System.currentTimeMillis()).toString();
                    log.info("\nReceived a Message from RabbitMQ Broker" + "\n\tTime:    " + time
                            + "\n\tTopic:   " + topic + "\n\tMessage: "
                            + new String(message.getPayload()) + "\n\tQoS:     "
                            + message.getQos() + "\n");

                    handleMQTTMessageService.handleMessageArrived(message);
                }

                public void connectionLost(Throwable cause) {
                    log.info("Connection to RabbitMQ broker lost!" + cause.getMessage());
                    latch.countDown();
                }

                public void deliveryComplete(IMqttDeliveryToken token) {
                    log.info("deliveryComplete");
                }

            });

            // Subscribe client to the topic filter with QoS level of 1
            log.info("Subscribing client to topic: " + topic);
            IMqttToken subToken = mqttClient.subscribe(topic, 1);
            subToken.waitForCompletion(10000);
            if (!subToken.isComplete() || subToken.getException() != null) {
                log.info("Error subscribing: " + subToken.getException());
                System.exit(-1);
            }
        } catch (MqttException me) {
            log.error("Error:", me);
        }
1
QoS = 0 doesn't retry or ensure delivery. Check the docs. hivemq.com/blog/…K.Nicholas
Thanks Nicholas. I understand that. Now I have another problem. With qos = 1, sometime broker does not publish all messages for subscribe. There are a few messages left in the broker and it is unacked. I'm not sure if the subscriber has received the news yet?Quang Trần Kỳ
Please make a new question if you have a new question and mark any appropriate answers as accepted. This is not a tutoring site.K.Nicholas

1 Answers

0
votes

QOS is independent for publishers and subscribers.

To ensure delivery to the subscribing client you need to subscribe at greater than QOS 0.

What happens to QOS 0 subscriptions depends on the broker, by default most will not queue messages for QOS 0 subscriptions, but mosquitto can be forced to with the queue_qos0_messages configuration flag