mqtt js 中乱码_mqtt之上RRPC同步调用实战
1.背景
MQTT协议是基于PUB/SUB的异步通信模式,不适用于服务端同步控制设备端返回结果的场景。物联网平台基于MQTT协议制定了一套请求和响应的同步机制,无需改动MQTT协议即可实现同步通信。物联网平台提供API给服务端,设备端只需要按照固定的格式回复PUB消息,服务端使用API,即可同步获取设备端的响应结果。
2.名词解释
RRPC:Revert-RPC。RPC(Remote Procedure Call)采用客户机/服务器模式,用户不需要了解底层技术协议,即可远程请求服务。RRPC则可以实现由服务端请求设备端并能够使设备端响应的功能。
3.RRPC原理
物联网平台收到来自用户服务器的RRPC调用,下发一条RRPC请求消息给设备。消息体为用户传入的数据,Topic为物联网平台定义的Topic,其中含有唯一的RRPC消息ID。
设备收到下行消息后,按照指定Topic格式(包含之前云端下发的唯一的RRPC消息ID)回复一条RRPC响应消息给云端,云端提取出Topic中的消息ID,和之前的RRPC请求消息匹配上,然后回复给用户服务器。
如果调用时设备不在线,云端会给用户服务器返回设备离线的错误;如果设备没有在超时时间内(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同步调用实战相关推荐
- mqtt js 中乱码_ES6中模块导入遇到的问题及其解决办法
" 阅读本文大概需要 5 分钟" 前言 今天遇到了一个小的问题,我们来看一下,情况是这样的:在没遇到过这个坑之前,如果需要引入一个模块,我通常的做法都是在HTML文件中内嵌一个sc ...
- mqtt js 中乱码_Vue.js 中的 v-cloak 指令——Vue学习之路
今天看一篇文档中见到了了v-cloak指令,感觉很新鲜.由于使用的频率不高.但还是想了解下是做什么的. 众所周知,程序的指令一般都是语义化的,然后,我企图从cloak这个单词能找到点线索. 然后发现, ...
- IoT平台实现RRPC同步调用最佳实战
简介: 满足云端下发指令给设备端,同时需要设备端返回响应结果的场景 基于Pub/Sub模式的同步调用实战 1.同步调用场景 1.1 背景 MQTT协议是基于PUB/SUB的异步通信模式,无法实现服务端 ...
- 微信小程序使用MQTT.JS中遇到的问题
一.需求:最近一个物联网项目,需要通过手机端微信小程序发布控制指令到设备,微信小程序端可以接收设备端的数据,于是用到了EMQX,通过MQTT.JS连接EMQX平台. 二.实现过程: 1.购买阿里云服务 ...
- JS中的数据类型(见《Jquery实战附录》)
一.所有数据类型的常量都看作对象. (一).JS自带的数据类型怎样创建对象? number.String这些基本类型的值,23."abc"等常量本身就是对象. Date类型:通过一 ...
- IoT 物联网平台自定义Topic同步调用RRPC实战(二)
RRPC:Revert-RPC.RPC(Remote Procedure Call)采用客户机/服务器模式,用户不需要了解底层技术协议,即可远程请求服务.RRPC则可以实现由服务端请求设备端并能够使设 ...
- 浅谈js中的this
js中,this自动引用正在调用的当前方法 . 前的对象.简而言之,this就是指向当前对象.举例说明: 1. obj.fun()中如果出现this.那么,this就是指向obj 2. new Fun ...
- js 中的this,默认绑定、隐式绑定、显式绑定、new绑定、箭头函数绑定详解
壹 ❀ 引 工具猴-免费在线工具-在线工具箱- 可以说this与闭包.原型链一样,属于JavaScript开发中老生常谈的问题了,百度一搜,this相关的文章铺天盖地.可开发好几年,被几道this题安 ...
- JS笔记(20): JS中的同步编程和异步编程
铺垫:关于定时器 定时器:设定一个定时器,并且设定了等到的时间,当到达指定的时间,浏览器会把对应的方法执行 1)常用的定时器 1.setTimeout(function,intarval) 执行一次 ...
最新文章
- Heap Dump分析工具ha456.jar
- Oracle-Soft Parse/Hard Parse/Soft Soft Parse解读
- pku 2195 Going Home 最小费最大流问题
- java 下对字符串的格式化
- 电气期刊论文实现:热电联产经济调度【有代码】
- Spring之Spring Boot
- wordpress 自定义分类url 重写_WordPress导航主题-WebStack导航主题
- 记一次成功部署kolla-ansible ocata版本过程
- P3840蜗牛一期--虚拟局域网VLAN
- Python作业:公鸡5元/只,母鸡3元/只,小鸡1元3只。问100元怎么买到100只。
- 解决QQ登录SDK不能网页授权登录的问题
- 价格行为交易策略:锤子十字线,Fakey,内部日烛线
- 28岁自学Python转行靠谱吗?入行晚吗?
- 吹爆这个Java 结构化数据处理开源库 SPL
- 旅行商问题(Traveling Salesman Problem,TSP)的+Leapms线性规划模型及c++调用
- RStudio安装后界面一片空白
- 磁通和磁通链,电感关系
- Android 输入法键盘和自定义表情面板
- Linux 中Tomcat 服务器 启动项目,页面删除报错“该信息被其他信息引用”解决 (ORA-02292)
- 五子棋1.0(Java单机版)