javamqtt

Program hangs while publishing message using qos = 0 in MQTT java


I am working on mqtt clients in thingstream. When I try to publish message to a topic using qos = 0, the message is sent but program hangs there only. Then I tried sending message using qos = 1. Message was sent successfully and program also didn't hanged. But while sending another message, I get interruption exception. Can anyone help me out.

Below is the snippet I am using to publish message.

MqttMessage message = new MqttMessage(command);
message.setPayload(command);
message.setQos(1);
mqttClient.publish(topic, message);
System.out.println("Message published");

Library used - org.eclipse.paho.client.mqttv3-1.2.0

Code for initializing mqtt client

public void connect() {

    try {
        mqttClient = new MqttClient(serverUri, clientId);
        //mqttClient.setTimeToWait(10000);
    } catch (MqttException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    mqttClient.setCallback(new MqttCallbackExtended() {
        @Override
        public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
            // TODO Auto-generated method stub
            System.out.println("messageArrived: " + topic.toString());
            System.out.println(mqttMessage.toString());
            System.out.println(mqttMessage.getPayload());
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken arg0) {
            // TODO Auto-generated method stub
            System.out.println("deliveryComplete: " + arg0.getMessageId());
        }

        @Override
        public void connectionLost(Throwable arg0) {
            // TODO Auto-generated method stub
            System.out.println("---Connection lost1");
            // Toast.makeText(App.getContext(), "Connection
            // lost",Toast.LENGTH_SHORT).show();

        }

        @Override
        public void connectComplete(boolean arg0, String arg1) {
            // TODO Auto-generated method stub
            System.out.println("connectComplete");
            try {
                mqttClient.subscribe("device/+/publish");
            } catch (MqttException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            try {
                commands.sendCommand(Commands.GET_STATUS, null, "device/identity:85111741-5789-3010-85c9-be4a7204e5d3");
            } catch (MqttException | InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    });

    MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
    mqttConnectOptions.setAutomaticReconnect(true);
    mqttConnectOptions.setCleanSession(true);
    mqttConnectOptions.setUserName(username);
    mqttConnectOptions.setPassword(password.toCharArray());
    mqttConnectOptions.setKeepAliveInterval(30);
    mqttConnectOptions.setConnectionTimeout(60);
    mqttConnectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);

    try {
        mqttClient.connect(mqttConnectOptions);
    } catch (MqttSecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (MqttException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

Solution

  • Do not send it in the main thread, use another thread instead to publish the message.

    Thread thread = new Thread() {
       public void run() {
           mqttClient.publish(topic, message);
       }  
    };
    thread.start(); 
    

    Regarding the comment about having a bunch of threads that don't finish, this does not appear to be the case. When running in its own thread, the publish call completes and the thread just created ends.

    It appears that calling publish in the main thread causes a thread lock. This would need to be looked further into as to whether this is a bug in the library or as designed, but calling publish in its own thread prevents wait lock.