1.背景

MQTT协议是基于PUB/SUB的异步通信模式,不适用于服务端同步控制设备端返回结果的场景。物联网平台基于MQTT协议制定了一套请求和响应的同步机制,无需改动MQTT协议即可实现同步通信。物联网平台提供API给服务端,设备端只需要按照固定的格式回复PUB消息,服务端使用API,即可同步获取设备端的响应结果。

2.名词解释

RRPC:Revert-RPC。RPC(Remote Procedure Call)采用客户机/服务器模式,用户不需要了解底层技术协议,即可远程请求服务。RRPC则可以实现由服务端请求设备端并能够使设备端响应的功能。

3.RRPC原理

  1. 物联网平台收到来自用户服务器的RRPC调用,下发一条RRPC请求消息给设备。消息体为用户传入的数据,Topic为物联网平台定义的Topic,其中含有唯一的RRPC消息ID。

  2. 设备收到下行消息后,按照指定Topic格式(包含之前云端下发的唯一的RRPC消息ID)回复一条RRPC响应消息给云端,云端提取出Topic中的消息ID,和之前的RRPC请求消息匹配上,然后回复给用户服务器。

  3. 如果调用时设备不在线,云端会给用户服务器返回设备离线的错误;如果设备没有在超时时间内(5秒内)回复RRPC响应消息,云端会给用户服务器返回超时错误。

3.1 设备端标识 ext=1

为了配合RRPC调用,设备端必须在进行MQTT CONNECT协议设置时,在clientId中增加ext=1参数:

3.2 RRPC通信Topic

RRPC调用的Topic格式如下:

其中${messageId}是IoT物联网平台生成的唯一的RRPC消息id,黑体部分是IoT物联网平台约定,红色部分可以根据业务场景自定义。

3.3 云端POP API调用

4.开发实战

4.1 设备端代码(Nodejs)

/**"dependencies": { "mqtt": "2.18.8" }*/const crypto = require('crypto');const mqtt = require('mqtt');//设备身份三元组+区域 

const deviceConfig = {    productKey: "替换productKey",    deviceName: "替换deviceName",    deviceSecret: "替换deviceSecret",    regionId: "cn-shanghai"};

const url = `tcp://${deviceConfig.productKey}.iot-as-mqtt.${deviceConfig.regionId}.aliyuncs.com:1883`;//2.建立连接const client = mqtt.connect(url, makeMqttOptions(deviceConfig));//3.监听RRPC指令client.subscribe(`/ext/rrpc/+/this/is/my/topic`)client.on('message', function(topic, message) {    console.log("topic=" + topic)    console.log("payloadJson=" + message)    //4.响应RRPC指令    if (topic.indexOf(`/ext/rrpc/`) > -1) {        client.publish(topic, JSON.stringify({ code: 200, msg: "rrpc ok" }));    }

})/*  生成MQTT连接参数*/function makeMqttOptions() {

    const params = {        productKey: deviceConfig.productKey,        deviceName: deviceConfig.deviceName,        timestamp: Date.now(),        clientId: Math.random().toString(36).substr(2),    }    //CONNECT参数    const options = {        keepalive: 60, //60s        clean: false, //cleanSession保持持久会话        protocolVersion: 4 //MQTT v3.1.1    }    //1.生成clientId,username,password    options.password = signHmacSha1(params, deviceConfig.deviceSecret);    options.clientId = `${params.clientId}|securemode=3,signmethod=hmacsha1,timestamp=${params.timestamp},ext=1|`;    options.username = `${params.deviceName}&${params.productKey}`;

    return options;}

/*  生成基于HmacSha1的password  参考文档:https://help.aliyun.com/document_detail/73742.html?#h2-url-1*/function signHmacSha1(params, deviceSecret) {

    let keys = Object.keys(params).sort();    // 按字典序排序    keys = keys.sort();    const list = [];    keys.map((key) => {        list.push(`${key}${params[key]}`);    });    const contentStr = list.join('');    return crypto.createHmac('sha1', deviceSecret).update(contentStr).digest('hex');}

4.2 服务端POP API调用代码(Nodejs)

const co = require('co');const RPCClient = require('@alicloud/pop-core').RPCClient;

const options = {    accessKey:"替换accessKey",    accessKeySecret: "替换accessKeySecret"};

//1.初始化clientconst client = new RPCClient({    accessKeyId: options.accessKey,    secretAccessKey: options.accessKeySecret,    endpoint: 'https://iot.cn-shanghai.aliyuncs.com',    apiVersion: '2018-01-20'});//2.构造RRPC参数const params = {    ProductKey: "你的产品ProductKey",    DeviceName: "你的设备DeviceName",    RequestBase64Byte: Buffer.from("Hello World").toString('base64'),    Timeout: 5000,    Topic:'/this/is/my/topic'};

co(function*() {    try {        //3.发起API调用        const response = yield client.request('RRpc', params);

        console.log(JSON.stringify(response));    } catch (err) {        console.log(err);    }});

4.3 实际运行效果

# 设备端日志$ node rrpc_client.js topic=/ext/rrpc/1128893568908287488/this/is/my/topicpayloadJson=Hello World

# 服务端日志$ node rrpc_Server.js {    "MessageId": "1128893568908287488",    "RequestId": "F9540921-8FDB-4671-B50A-84D119DA56D4",    "PayloadBase64Byte": "eyJjb2RlIjoyMDAsIm1zZyI6InJycGMgb2sifQ==",    "Success": true,    "RrpcCode": "SUCCESS"}

其中 eyJjb2RlIjoyMDAsIm1zZyI6InJycGMgb2sifQ== 解码后即:{ code: 200, msg: "rrpc ok" }

4.4 IoT物联网平台 日志服务

mqtt js 中乱码_mqtt之上RRPC同步调用实战相关推荐

  1. mqtt js 中乱码_ES6中模块导入遇到的问题及其解决办法

    " 阅读本文大概需要 5 分钟" 前言 今天遇到了一个小的问题,我们来看一下,情况是这样的:在没遇到过这个坑之前,如果需要引入一个模块,我通常的做法都是在HTML文件中内嵌一个sc ...

  2. mqtt js 中乱码_Vue.js 中的 v-cloak 指令——Vue学习之路

    今天看一篇文档中见到了了v-cloak指令,感觉很新鲜.由于使用的频率不高.但还是想了解下是做什么的. 众所周知,程序的指令一般都是语义化的,然后,我企图从cloak这个单词能找到点线索. 然后发现, ...

  3. IoT平台实现RRPC同步调用最佳实战

    简介: 满足云端下发指令给设备端,同时需要设备端返回响应结果的场景 基于Pub/Sub模式的同步调用实战 1.同步调用场景 1.1 背景 MQTT协议是基于PUB/SUB的异步通信模式,无法实现服务端 ...

  4. 微信小程序使用MQTT.JS中遇到的问题

    一.需求:最近一个物联网项目,需要通过手机端微信小程序发布控制指令到设备,微信小程序端可以接收设备端的数据,于是用到了EMQX,通过MQTT.JS连接EMQX平台. 二.实现过程: 1.购买阿里云服务 ...

  5. JS中的数据类型(见《Jquery实战附录》)

    一.所有数据类型的常量都看作对象. (一).JS自带的数据类型怎样创建对象? number.String这些基本类型的值,23."abc"等常量本身就是对象. Date类型:通过一 ...

  6. IoT 物联网平台自定义Topic同步调用RRPC实战(二)

    RRPC:Revert-RPC.RPC(Remote Procedure Call)采用客户机/服务器模式,用户不需要了解底层技术协议,即可远程请求服务.RRPC则可以实现由服务端请求设备端并能够使设 ...

  7. 浅谈js中的this

    js中,this自动引用正在调用的当前方法 . 前的对象.简而言之,this就是指向当前对象.举例说明: 1. obj.fun()中如果出现this.那么,this就是指向obj 2. new Fun ...

  8. js 中的this,默认绑定、隐式绑定、显式绑定、new绑定、箭头函数绑定详解

    壹 ❀ 引 工具猴-免费在线工具-在线工具箱- 可以说this与闭包.原型链一样,属于JavaScript开发中老生常谈的问题了,百度一搜,this相关的文章铺天盖地.可开发好几年,被几道this题安 ...

  9. JS笔记(20): JS中的同步编程和异步编程

    铺垫:关于定时器 定时器:设定一个定时器,并且设定了等到的时间,当到达指定的时间,浏览器会把对应的方法执行 1)常用的定时器 1.setTimeout(function,intarval) 执行一次 ...

最新文章

  1. Heap Dump分析工具ha456.jar
  2. Oracle-Soft Parse/Hard Parse/Soft Soft Parse解读
  3. pku 2195 Going Home 最小费最大流问题
  4. java 下对字符串的格式化
  5. 电气期刊论文实现:热电联产经济调度【有代码】
  6. Spring之Spring Boot
  7. wordpress 自定义分类url 重写_WordPress导航主题-WebStack导航主题
  8. 记一次成功部署kolla-ansible ocata版本过程
  9. P3840蜗牛一期--虚拟局域网VLAN
  10. Python作业:公鸡5元/只,母鸡3元/只,小鸡1元3只。问100元怎么买到100只。
  11. 解决QQ登录SDK不能网页授权登录的问题
  12. 价格行为交易策略:锤子十字线,Fakey,内部日烛线
  13. 28岁自学Python转行靠谱吗?入行晚吗?
  14. 吹爆这个Java 结构化数据处理开源库 SPL
  15. 旅行商问题(Traveling Salesman Problem,TSP)的+Leapms线性规划模型及c++调用
  16. RStudio安装后界面一片空白
  17. 磁通和磁通链,电感关系
  18. Android 输入法键盘和自定义表情面板
  19. Linux 中Tomcat 服务器 启动项目,页面删除报错“该信息被其他信息引用”解决 (ORA-02292)
  20. 五子棋1.0(Java单机版)

热门文章

  1. harbor-offline-installer-v2.1.0.tgz 分享
  2. 重置mysql密码的命令
  3. deepin/Ubuntu安装最新版docker-ce命令整理
  4. 【收藏】最详细的cmder配置
  5. golang beego安装及入门示例
  6. k8s Dashboard部署Tomcat集群
  7. Python3字符串填充和对齐代码示例
  8. Spring JdbcTemplate CRUD增删改查操作
  9. Spring注解开发-@Scope作用域注解
  10. php连接数据库语言,PHP语言连接MYSQL数据库实例代码