MQTT.fx is an Eclipse Paho-based Message Queuing Telemetry Transport (MQTT) client that is written in Java. It supports Windows, Mac, and Linux operating systems. It can be used to verify whether a device can connect to IoT Platform. MQTT.fx allows you to subscribe to and publish messages by using topics. This article describes how to connect a simulated device to IoT Platform over MQTT by using MQTT.fx on Windows.

Prerequisites

A product and a device are created in the IoT Platform console.The device certificate informationincluding ProductKey, DeviceName, and DeviceSecret is obtained. For more information, see the following articles:

Notice The MQTT.fx tool is used to simulate an online device and supports transmitting non-passthrough data. To transmit pass-through data, you can use an actual device or an SDK for testing.

Configure MQTT.fx

  1. Download MQTT.fx v1.7.1 for Windows and install the MQTT.fx tool.
    For more information, visit the MQTT.fx official website.
  2. Open the MQTT.fx tool, click Extras in the menu bar, and then select Edit Connection Profiles.
    Set MQTT parameters
  3. On the Edit Connection Profiles page, set the parameters.
    1. Edit the basic information.
      Edit the basic information of MQTT.fx
      Parameter Description Example
      Profile Name Enter a custom name. iot connection
      Profile Type Specify a connection mode. Select MQTT Broker.
      MQTT Broker Profile Settings
      Broker Address Enter an endpoint.

      Format: ${YourProductKey}.iot-as-mqtt.${YourRegionId}.aliyuncs.com.

      • ${YourProductKey}: Replace this variable with the ProductKey of the product to which the device belongs.

        You can view the ProductKey on the Device Details page in the IoT Platform console.

        within the validity period before you enable the feature.
      • ${YourRegionId}: Replace this variable with your region ID. For information about region IDs, see Regions and zones.
      a1oGs******.iot-as-mqtt.cn-shanghai.aliyuncs.com
      • a1oGs****** indicates the ProductKey.
      • cn-shanghai indicates the region ID.
      Broker Port Enter a port number. Set this parameter to 1883.
      Client ID Specify the fields in the MQTTprotocol.

      Format: ${ClientId}|securemode=${Mode},signmethod=${SignMethod}|.

      Variables:

      • ${ClientId}: the ID of the client, such as a device, application, or web browser. You can specify a client ID as needed. The client ID must be 1 to 64 characters in length. In most cases, the client ID is the device ID. We recommend that you use the MAC address or serial number (SN) of the device as the client ID.
      • ${Mode}: the security mode.
        • If you use a direct TCP connection, specify securemode=3. In this case, you do not need to set the SSL/TLS parameters.
        • If you use a direct TLS connection, specify securemode=2. In this case, you must set the SSL/TLS parameters.
      • ${SignMethod}: the signature algorithm. Valid values: hmacmd5 and hmacsha1.
      Notice
      • Do not confuse the usage of the Client ID parameter and the ${ClientId} variable.
      • Do not omit the vertical bars (|) between and at the end of the parameters.
      • When you set parameters, make sure that you remove all spaces from parameter values.
      • After you specify the Client ID parameter, do not click Generate.

      In this example, the value of the ${ClientId} variable is 12345. A direct TLS connection is used. The signature algorithm is hmacsha1.

      12345|securemode=2,signmethod=hmacsha1|

      General

      In this example, the default values of the parameters are used. You can set the parameters based on your business requirements.
    2. Click the User Credentials tab. Set the User Name and Password parameters.
      Set the User Credentials parameters of MQTT.fx
      Parameter Description Example
      User Name The username consists of a DeviceName, ampersand (&), and ProductKey.

      Format: ${YourDeviceName}&${YourProductKey}.

      Light&a1oGs******
      • Light indicates the DeviceName of the device.
      • a1oGs****** indicates the ProductKey of the device.
      Password To generate a password, you must select a signature algorithm, use the DeviceSecret of the device as a secret key, and then concatenate the required parameters and their values.
      Notice
      • Your MQTT.fx client may show a masked password. If a password is pasted, the pointer moves to the end of the password. In this case, you do not need to paste the password again.
      • Make sure that you specify valid uppercase and lowercase letters in parameter names and values.

      You can use one of the following methods to generate a password:

      • Use a generation tool:

        Click MQTT_Password to download the tool. After you decompress the file, double-click the sign.html file and then set the parameters as prompted to generate a password.

        • productKey, deviceName, and deviceSecret: the information of the device certificate. You can view the certificate on the Device Details page of the IoT Platform console.
        • timestamp: the timestamp. This parameter is optional.
        • clientId: the ID of the device. The value of this parameter must be the same as the value of the ${ClientId} variable that you set in the Client ID parameter.
        • method: the signature algorithm. The value of the parameter must be the same as the value of the ${SignMethod} variable that you set in the Client ID parameter.
      • Manually generate a password by using an encryption function. The hmacsha1() function is used in this example. For more information about the sample code, see Appendix: Sample code for encryption.

        The field value varies based on the following operation types:

        • ${productKey}, ${deviceName}, and ${deviceSecret}: Replace the variables with your device certificate information.
        • ${clientId}: Replace this variable with the value of the ${ClientId} variable that you set in the Client ID parameter.
      • Example of generating a password by using the toolExample of generating a password by using the tool
      • Example of manually generating a password

        The timestamp parameter is not specified in this example.

        Encryption function
    3. If you use a TLS connection (securemode=2), click the SSL/TLS tab, select Enable SSL/TLS, and then set Protocol to TLSv1.2.
      Notice If you use a TCP connection (securemode=3), use the default settings on the SSL/TLS tab, and go to the next step.
      Set the SSL/TLS parameters of MQTT.fx
  4. Click OK in the lower-right corner.
  5. Click Connect.
    If the indicator on the right side turns green, the connection is established. Connect the MQTT.fx client to IoT Platform

    You can view the status of the device in the IoT Platform console.Choose Devices > Devices, select the product, and then find the device. The device is in the Online state.

In the following sections, downstream messaging and upstream messaging are tested to verify whether the MQTT.fx client is connected to IoT Platform. If your test results are different from the following sample results, the connection is not established. You must modify settings based on logs.

Test downstream messaging

  1. Log on to the IoT Platform console.On the Product Details page, choose Topic Categories > Custom Topics. Then, find a custom topic that has the Subscribe permission.
    The following topic is used in this example: /a1oGs4X***/${deviceName}/user/get. You must replace the ${deviceName} variable with Light.

    For more information, see Edit a topic category.

  2. In the MQTT.fx tool, click Subscribe. In the Subscribe field, enter the topic that is specified in the previous step, and then click Subscribe.

    After the subscription succeeds, the custom topic is displayed on the Subscribe tab.

    Custom topics are displayed on the Subscribe tab
  3. Go to the Device Details page in the IoT Platform console. On the Topic List tab, find the topic and click Publish Message.
    Publish messages to a topic that is subscribed by MQTT.fx
  4. Enter a message and click OK.
    Enter a message that you want to publish to the topic
  5. In the MQTT.fx tool, check whether the message is received.
    Check whether MQTT.fx receives the message
  6. Go to the Device Details page in the IoT Platform console. On the Device Log tab, click View. On the Device Log page, view cloud-to-device messages.

Test upstream messaging

  1. Log on to the IoT Platform console.On the Product Details page, choose Topic Categories > Custom Topics. Then, find a custom topic that has the Subscribe permission.
    The following topic is used in this example: /a1oGs4X***/${deviceName}/user/get. You must replace the ${deviceName} variable with Light.

    For more information, see Edit a topic category.

  2. In the MQTT.fx tool, click Publish. In the Publish field, enter the topic that is specified in the previous step. In the editor, enter the message to be sent and click Publish.
    Publish messages in MQTT.fx
  3. Go to the Device Details page in the IoT Platform console. On the Device Log tab, click View. On the Device Log page, view device-to-cloud messages.
    View the message that is published to IoT Platform by MQTT.fx

View logs

In the MQTT.fx tool, click the Log tab. On the tab that appears, view operation logs and error logs.

View logs in MQTT.fx

Appendix: Sample code for encryption

package com.aliyun.iot.util;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class SignDemo {

    public static String sign(Map<String, String> params, String deviceSecret, String signMethod) {
        // Sort the parameter keys in dictionary order.
        String[] sortedKeys = params.keySet().toArray(new String[] {});
        Arrays.sort(sortedKeys);

        // Generate a canonicalized request string.
        StringBuilder canonicalizedQueryString = new StringBuilder();
        for (String key : sortedKeys) {
            if ("sign".equalsIgnoreCase(key)) {
                continue;
            }
            canonicalizedQueryString.append(key).append(params.get(key));
        }

        try {
            String key = deviceSecret;
            return encryptHMAC(signMethod, canonicalizedQueryString.toString(), key);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String encryptHMAC(String signMethod, String content, String key) throws Exception {
        SecretKey secretKey = new SecretKeySpec(key.getBytes("utf-8"), signMethod);
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());
        mac.init(secretKey);
        byte[] data = mac.doFinal(content.getBytes("utf-8"));
        return bytesToHexString(data);
    }

    public static final String bytesToHexString(byte[] bArray) {

        StringBuffer sb = new StringBuffer(bArray.length);
        String sTemp;
        for (int i = 0; i < bArray.length; i++) {
            sTemp = Integer.toHexString(0xFF & bArray[i]);
            if (sTemp.length() < 2) {
                sb.append(0);
            }
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }

    public static void main(String args[]) {
        
        Map<String, String> params = new HashMap<String, String>();
        params.put("productKey", "${productKey}");
        params.put("deviceName", "${deviceName}");
        params.put("clientId", "${clientId}");
        // The timestamp. This parameter is optional. When you specify this parameter, delete the forward slashes (//) before the following two lines of code.
        //String t = System.currentTimeMillis() + "";
        //params.put("timestamp", t);

        String sign = SignDemo.sign(params, "${deviceSecret}", "hmacsha1");
        System.out.print(sign);
    }

}