1

I am trying to subscribe events from IBM IoT platform.

The example I tested is from an IBM blog: https://www.ibm.com/developerworks/library/iot-mobile-phone-iot-device-bluemix-apps-trs/. In this link, the codes can be downloaded.

With this example, the Android app can successfully connect and publish events to the IBM IoT platform, but when I tried "subscribe", I always receive the error "Connection lost". What causes this problem? Thank you!

The relevant codes are:

public IMqttToken subscribeToEvent(String deviceType, String deviceId, String event, String format, int qos, Object userContext, IMqttActionListener listener) throws MqttException {
    String eventTopic = "iot-2/type/" + deviceType + "/id/" + deviceId + "/evt/" + event + "/fmt/"+format;
    return subscribe(eventTopic, qos, userContext, listener);
}

public static void subscribeEvent(Context context,String event) {
    Log.v(TAG, ".subscribeEvent() entered")

    try {
        MyIoTActionListener listener = new MyIoTActionListener(context, Constants.ActionStateStatus.SUBSCRIBE);
        IoTClient iotClient = IoTClient.getInstance(context);
        String deviceType = "Android";
        String deviceId = "...";
        iotClient.subscribeToEvent(deviceType, deviceId, event, "json", 0, context,listener);

    } catch (MqttException e) {
        Log.d(TAG, ".SubscribeEvent() received exception on SubscribeEvent()");
    }
}

The connection URL is:

String connectionURI = "tcp://" + this.getOrganization() + ".messaging.internetofthings.ibmcloud.com:1883";

ssl somehow cannot work.

Qinrui
  • 21
  • 3
  • how do you authenticate? do you use the token generated when you have created the device id? If you the subscribe action to topic String eventTopic = "iot-2/type/" + deviceType + "/id/" + deviceId + "/evt/" + event + "/fmt/"+format; is not allowed and connection is closed. Try and generate an API key and token and use them to authenticate and subscribe. – idan Jan 03 '18 at 11:52
  • Thank you idan! Now I have solved this problem. A device client can only publish its events and subscribe commands. An application client can publish and subscribe events and commands. When I tried to subscribe an event with the device client, it obviously failed. – Qinrui Jan 11 '18 at 08:49
  • yes, you are right, that is why I've asked how the authentication is done. Glad it is working now. – idan Jan 12 '18 at 09:42

1 Answers1

0

This problem has been solved.

Two concepts have to be clarified: device client and application client.

A device client can only publish events and subscribe commands. In the question, I subscribe events with a device client, the IoT platform cannot response and returns the error "Connection Lost". The correct way to code is:

    public IMqttToken subscribeToCommand(String command, String format, int qos, Object userContext, IMqttActionListener listener) throws MqttException {
        String commandTopic = getCommandTopic(command, format);
        return subscribe(commandTopic, qos, userContext, listener);
    }

public static String getCommandTopic(String command, String format) {
        return "iot-2/cmd/" + command + "/fmt/json";
    }

public static void subscribeCommand(Context context, String command) {
        try {
            MyIoTActionListener listener = new MyIoTActionListener(context, Constants.ActionStateStatus.SUBSCRIBE);
            IoTClient iotClient = IoTClient.getInstance(context);

        iotClient.subscribeToCommand(command, "json", 0, context,listener);
    } catch (MqttException e) {
        Log.d(TAG, ".SubscribeCommand() received exception on SubscribeEvent()");
    }
}

The example provided by IBM contains functions like subscribeEvent and publishCommand for a device client. These functions make me confused.

If you want to publish commands and subscribe events, an application client need to be created. The method to create an application client is:

import com.ibm.iotf.client.app.ApplicationClient;

Properties appProperties = new Properties();
appProperties.put("id",applicationId);
appProperties.put("Organization-ID",organizationId);
appProperties.put("Authentication-Method","apikey");
appProperties.put("API-Key",apiKey);
appProperties.put("Authentication-Token",token);

appClient = new ApplicationClient(appProperties);

appClient.connect();

See more about application client at https://github.com/ibm-watson-iot/iot-java/blob/master/src/main/java/com/ibm/iotf/client/app/ApplicationClient.java

Qinrui
  • 21
  • 3