文档首页 > > 开发指南> 设备侧开发> 使用MQTT协议接入

使用MQTT协议接入

分享
更新时间: 2020/03/13 GMT+08:00

MQTT是非安全的基于TCP的非加密协议,而MQTTS是安全的基于TLS的加密协议。

采用MQTT协议接入物联网平台的设备,设备与物联网平台之间的通信过程,数据没有加密,建议使用MQTTS协议。

按照本文档的指导,开发者可以通过MQTT协议快速接入平台,通过平台接口实现“数据上报”“命令下发”的功能。

  • mqttdemo使用的开发语言为Java,包含mqtt不加密/mqtts加密接入两种方式。如需其他语言接入,请参考资源获取
  • mqttdemo使用的IDE工具为IntelliJ IDEA

创建产品模型并注册设备

  1. 登录物联网平台控制台,选择“设备接入”
  2. 查看MQTT设备接入地址,保存该地址。

  3. 在设备管理页面选择产品模型,单击“新增产品模型”,选择“手动创建”。创建一个基于MQTT协议的产品模型。

  4. 点击 设备 > 设备注册,选择“单个注册”页签,选择步骤3中创建的产品模型。

  5. 设备注册成功后保存设备标识码、设备ID、密钥。

导入代码样例

  1. 下载mqttdemo.zip样例。
  2. 打开IDEA开发者工具,点击 Import Project。

  3. 选择步骤1中下载的样例,然后根据界面提示,单击“next”

  4. 完成代码导入。

建立连接

设备或网关在接入物联网平台时首先需要和平台建立连接,从而将设备或网关与平台进行关联。开发者通过传入设备信息,将设备或网关连接到物联网平台。

在建立连接之前,先修改以下参数

//IoT平台mqtt对接地址
static String serverIp = "iot-acc.cn-north-4.myhuaweicloud.com";
//注册设备时获得的deviceId,密钥(要替换为自己注册的设备ID与密钥)
static String deviceId = "722cbd56-fc38-4d92-b61d-b5a061972d02";
static String secret = "123456789";

serverIp为物联网平台的设备对接地址,可参考平台对接信息获取(获取的是域名信息,可通过在cmd命令框中执行“ping 域名”,获取IP地址)。

1883是mqtt接入端口,8883是mqtts接入端口。

deviceId和secret为设备ID和密钥,在步骤5中获取。

修改完上图的参数后就可使用MqttClient建立连接了。
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(false);
options.setKeepAliveInterval(120);  //心跳时间限定为30至1200秒
options.setConnectionTimeout(5000);
options.setAutomaticReconnect(true);
options.setUserName(deviceId);
options.setPassword(getPassword().toCharArray());
client = new MqttAsyncClient(url, getClientId());
client.setCallback(callback);

如果建立MQTTS连接,需要加载服务器端SSL证书,需要添加SocketFactory参数。 ca.jks是IoT平台的服务器端证书,在demo的resources目录下。

options.setSocketFactory(getOptionSocketFactory(MqttDemo.class.getClassLoader().getResource("ca.jks").getPath()));

调用client.connect(options, null, new IMqttActionListener())发起连接。连接时,需要向函数传入MqttConnectOptions连接参数。

client.connect(options, null, new IMqttActionListener()

在创建MqttConnectOptions连接参数时,调用options.setPassword()传入的密码会做一个加密。getPassword()为获取加密后的密钥

public static String getPassword() {
    return sha256_mac(secret, getTimeStamp());
}
/* 调用sha256算法进行哈希 */
public static String sha256_mac(String message, String tStamp) {    
    String passWord = null;
    try {        
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");        
        SecretKeySpec secret_key = new SecretKeySpec(tStamp.getBytes(), "HmacSHA256");        
        sha256_HMAC.init(secret_key);byte[] bytes = sha256_HMAC.doFinal(message.getBytes());        
        passWord = byteArrayToHexString(bytes);    
    }catch (Exception e) {
        LOGGER.info("Error HmacSHA256 ===========" + e.getMessage());    
    }
    return passWord;

订阅接收命令

//订阅接收命令
client.subscribe(getCmdRequestTopic(), qosLevel, null, new IMqttActionListener();
getCmdRequestTopic()获取接收命令的topic,向平台订阅该topic的命令。
public static String getCmdRequestTopic() {
    return "$oc/devices/" + deviceId + "/sys/commands/#";
}

属性上报

//上报json数据,注意serviceId要与Profile中的定义对应
String jsonMsg = "{\"services\": [{\"service_id\": \"Temperature\",\"properties\": {\"value\": 57}},{\"service_id\": \"Battery\",\"properties\": {\"level\": 80}}]}";
MqttMessage message = new MqttMessage(jsonMsg.getBytes());
client.publish(getRreportTopic(), message, qosLevel, new IMqttActionListener();

消息体jsonMsg组装格式为JSON,其中service_id要与Profile中的定义对应,properties是设备的属性,57为对应的属性值。event_time为可选项,为设备采集数据UTC时间,不填写默认使用系统时间。

设备或网关成功连接到物联网平台后,即可调用MqttClient.publish(String topic,MqttMessage message)向平台上报设备属性值。

getRreportTopic()即为获取上报数据的topic。
public static String getRreportTopic() {
    return "$oc/devices/" + deviceId + "/sys/properties/report";
}

查看上报数据

运行main方法成功启动后,即可在设备管理界面查看上报的设备属性数据。

分享:

    相关文档

    相关产品

文档是否有解决您的问题?

提交成功!

非常感谢您的反馈,我们会继续努力做到更好!

反馈提交失败,请稍后再试!

*必选

请至少选择或填写一项反馈信息

字符长度不能超过200

提交反馈 取消

如您有其它疑问,您也可以通过华为云社区问答频道来与我们联系探讨

跳转到云社区