更新时间:2024-08-21 GMT+08:00

Node.js Demo使用说明

概述

本文以Node.js为例,介绍通过MQTTS/MQTT协议接入平台,基于平台接口实现“属性上报”“订阅接收命令”等功能。

本文中使用的代码为样例代码,仅用于体验平台通信功能,如需进行商用,可以参考资源获取获取对应语言的IoT Device SDK进行集成。

前提条件

准备工作

  1. 安装Node.js访问Node.js官网,选择合适系统的版本下载。(本文以windows 64-bit系统,Node.js版本v12.18.0(npm 6.14.4)为例)。

  2. 下载完成后,运行安装文件,根据界面提示安装。
  3. 检查Node.js是否安装成功。

    Win键 + r -->输入 cmd-->回车,进入命令行窗口。

    输入node –v,回车后显示Node.js版本,输入npm -v显示版本信息,即表示安装成功。

导入代码样例

  1. 下载quickStart(Node.js)样例,并解压。
  2. 运行Win键 + r -->输入 cmd-->回车,进入命令行窗口,安装全局模块,执行如下命令:

    npm install mqtt -g:mqtt协议模块;

    npm install crypto-js -g:设备密钥加密算法模块;

    npm install fs -g:用于加载平台证书;

  3. 找到文件解压的对应目录,如下图所示。

    代码目录介绍如下:
    • DigiCertGlobalRootCA.crt.pem:平台证书文件;
    • MqttDemo.js:Node.js源码,包含MQTT/MQTTS连接到平台,并进行属性上报,命令下发;

  4. Demo里的关键工程配置参数。其中MqttDemo.js需要配置Server地址、设备ID和设备密钥,用于启动Demo时,连接控制台上注册的设备。

    var TRUSTED_CA = fs.readFileSync("DigiCertGlobalRootCA.crt.pem");//获取证书
    
    //IoT平台mqtt对接地址
    var serverUrl = "****"; //请填写设备所在平台的接入地址
    var deviceId = "****";//请填写在平台注册的设备ID
    var secret = "****";//请填写在平台注册的设备密钥
    var timestamp = dateFormat("YYYYmmddHH", new Date());
    
    var propertiesReportJson = {'services':[{'properties':{'alarm':1,'temperature':12.670784,'humidity':18.37673,'smokeConcentration':19.97906},'service_id':'smokeDetector','event_time':null}]};
    var responseReqJson = {'result_code': 0,'response_name': 'COMMAND_RESPONSE','paras': {'result': 'success'}};

  5. 用户可通过mqtt.connect(options)中选择不同的options,确定设备侧建链时是否进行SSL加密,建议使用默认的MQTTS安全连接。

    //MQTTS安全连接
    var options = {
        host: serverUrl,
        port: 8883,
        clientId: getClientId(deviceId),
        username: deviceId,
        password:HmacSHA256(secret, timestamp).toString(),
        ca: TRUSTED_CA,
        protocol: 'mqtts',
        rejectUnauthorized: false,
        keepalive: 120,
        reconnectPeriod: 10000,
        connectTimeout: 30000
    }
    
    //MQTT非安全连接,不建议使用
    var option = {
        host: serverUrl,
        port: 1883,
        clientId: getClientId(deviceId),
        username: deviceId,
        password: HmacSHA256(secret, timestamp).toString(),
        keepalive: 120,
        reconnectPeriod: 10000,
        connectTimeout: 30000
        //protocol: 'mqtts'
        //rejectUnauthorized: false
    }
    
    //此处默认使用options为安全连接
    var client = mqtt.connect(options);

程序启动

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

  1. 此Demo主要提供建立MQTT/MQTTS连接等方法,MQTT使用1883端口,MQTTS使用8883端口(需要加载设备校验平台身份的证书,用于设备侧接入物联网平台登录鉴权使用),并提供了Mqtt客户端建立连接的方法mqtt.connect(options)。
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    var client = mqtt.connect(options);
    
    client.on('connect', function () {
        log("connect to mqtt server success, deviceId is " + deviceId);
        //订阅Topic
        subScribeTopic();
        //发布消息
        publishMessage();
    })
    
    //命令下发响应
    client.on('message', function (topic, message) {
        log('received message is ' + message.toString());
    
        var jsonMsg = responseReq;
        client.publish(getResponseTopic(topic.toString().split("=")[1]), jsonMsg);
        log('responsed message is ' + jsonMsg);
    })
    

    找到Node.js Demo源码目录,修改关键工程配置参数后启动程序,如下图:

    启动程序前,设备状态是离线。

    图1 设备列表-设备离线

    启动程序后,设备状态变为在线

    图2 设备列表-设备在线

    注:如果连接失败,在重连回调函数中已实现退避重连,代码样例如下:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    client.on('reconnect', () => {
    
        log("reconnect is starting");
    	
        //退避重连
        var lowBound = Number(defaultBackoff)*Number(0.8);
        var highBound = Number(defaultBackoff)*Number(1.2);
    	
        var randomBackOff = parseInt(Math.random()*(highBound-lowBound+1),10);
    	
        var backOffWithJitter = (Math.pow(2.0, retryTimes)) * (randomBackOff + lowBound);
    	
        var waitTImeUtilNextRetry = (minBackoff + backOffWithJitter) > maxBackoff ? maxBackoff : (minBackoff + backOffWithJitter);
    	
        client.options.reconnectPeriod = waitTImeUtilNextRetry;
    	
        log("next retry time: " + waitTImeUtilNextRetry);
    	
        retryTimes++;
    })
    
  2. 订阅某Topic的设备才能接收broker发布的关于该Topic的消息,关于平台预置Topic可参考Topic定义。此Demo调用subScribeTopic方法进行订阅Topic,订阅成功后等待平台命令下发:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    //订阅接收命令topic
    function subScribeTopic() {
        client.subscribe(getCmdRequestTopic(), function (err) {
            if (err) {
                log("subscribe error:" + err);
            } else {
                log("topic : " + getCmdRequestTopic() + " is subscribed success");
            }
        })
    }
    
  3. 发布Topic是指设备主动向平台上报自己的属性或消息,详细见设备属性上报接口文档。连接成功后,调用publishMessage方法进行属性上报:
    1
    2
    3
    4
    5
    6
    7
    8
    //上报json数据,注意serviceId要与Profile中的定义对应
    function publishMessage() {
        var jsonMsg = propertiesReport;
        log("publish message topic is " + getReportTopic());
        log("publish message is " + jsonMsg);
        client.publish(getReportTopic(), jsonMsg);
        log("publish message successful");
    }
    
    上报属性的json:
    1
    var propertiesReportJson = {'services':[{'properties':{'alarm':1,'temperature':12.670784,'humidity':18.37673,'smokeConcentration':19.97906},'service_id':'smokeDetector','event_time':null}]};
    

    命令行主界面如下:

    属性上报成功,平台界面如下:

    图3 查看上报数据-Demo_smokeDetector

    如果在“设备详情”页面没有最新上报数据,请修改产品模型中服务和属性的内容,确保设备上报的服务/属性和产品模型中的服务/属性一致,或者进入产品基本信息页面,删除所有服务。

接收下发命令

在Demo中提供了接收平台下发命令的功能,在MQTT建链完成并成功订阅Topic后,可以在管理控制台设备详情中命令下发或使用应用侧Demo对该设备ID进行命令下发。下发成功后,在Demo中接收到平台下发给设备的命令。

例如下发参数名为smokeDetector: SILENCE,参数值为50的命令。

图4 命令下发-SILENCE

命令下发成功后,Demo收到的消息是50,命令运行主界面显示如下:

由于是同步命令需要端侧回复响应可参考接口