MQTT协议是基于Pub/Sub的异步通信模式,无法实现HTTP协议的同步响应业务处理结果,导致云端业务系统开发难度高。
为了适应智能灯开灯,智能锁开锁,充电宝弹出,自动售货机付款后出货,按摩椅启动等业务场景,IoT物联网平台基于MQTT协议制定了一套请求和响应的同步机制,无需改动MQTT协议即可实现同步通信。应用服务器通过POP API发起RRPC调用,IoT设备端只需要在Timeout内,按照固定的格式回复Pub消息,服务端即可同步获取IoT设备端的响应结果。
技术原理
服务端同步RRPC调用业务流程如下:
Topic格式约定:
设备端开发
我们以充电桩场景为例,用户完成付款后,服务端推送充电指令,并实时获取设备处理结果。
指令如下:
{"power":200,"port":3}
设备响应:
{"bizCode": 0,"errMsg":"xxxxx"};// 0 成功,400 充电失败
创建充电桩产品,并注册设备。
设备端监听RRPC指令Topic,开启指定把枪充电,并返回响应结果。示例代码如下:
const mqtt = require('aliyun-iot-mqtt');
// 1.设备身份三元组
const options = {
productKey: "Your productKey",
deviceName: "Your deviceName",
deviceSecret: "Your deviceSecret",
regionId:"cn-shanghai"
};
// 2.建立连接
const client = mqtt.getAliyunIotMqttClient(options);
// 3.订阅RRPC主题
client.subscribe(`/sys/${options.productKey}/${options.deviceName}/rrpc/request/+`)
client.on('message', function(topic, message) {
if(topic.indexOf(`/sys/${options.productKey}/${options.deviceName}/rrpc/request/`)>-1){
// 4.接收并处理业务,响应RRPC指令
handleRrpc(topic, message)
}
})
function handleRrpc(topic, message){
topic = topic.replace('/request/','/response/');
console.log("topic=" + topic)
console.log("payload=" + message)
//响应RRPC指令 payload自定义
const payloadJson = {bizCode:0};// 0 成功,400 充电失败
client.publish(topic, JSON.stringify(payloadJson));
}
服务端开发
服务端通过RRPC API即可发起同步调用,实时获取设备端响应结果。
RRPC API文档地址:
https://help.aliyun.com/document_detail/69797.html
我们以Node.js发起同步调用,代码示例:
const co = require('co');
const RPCClient = require('@alicloud/pop-core').RPCClient;
const options = {
accessKey: "Your accessKey",
accessKeySecret: "Your accessKeySecret"
};
// 1.初始化client
const client = new RPCClient({
accessKeyId: options.accessKey,
secretAccessKey: options.accessKeySecret,
endpoint: 'https://iot.cn-shanghai.aliyuncs.com',
apiVersion: '2018-01-20',
opts: {
timeout: 9000
}
});
// 指令内容
const payload = {
power: 200,
port: 3
};
// 2.构建RRPC 请求
const params = {
ProductKey: "Your ProductKey",
DeviceName: "Your DeviceName",
RequestBase64Byte: new Buffer(JSON.stringify(payload)).toString("base64"),
Timeout: 8000
};
co(function*() {
// 3.发起API调用
try {
const response = yield client.request('Rrpc', params);
console.log(JSON.stringify(response));
console.log(response.RrpcCode);
if (response.RrpcCode == "SUCCESS") {
var resultJSON = new Buffer(response.PayloadBase64Byte, 'base64').toString();
console.log("RRPC SUCCESS =====>", JSON.stringify(JSON.parse(resultJSON)));
}
} catch (err) {
console.log("RRPC ERROR =====>", JSON.stringify(err.data));
}
});
联机调试
正常响应结果:
控制台日志:
异常响应结果,设备超时:
控制台日志:
异常响应结果,设备离线:
控制台日志:
【往期回顾】