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

简介: 满足云端下发指令给设备端,同时需要设备端返回响应结果的场景

基于Pub/Sub模式的同步调用实战

1.同步调用场景

1.1 背景

MQTT协议是基于PUB/SUB的异步通信模式,无法实现服务端下发指令给设备端,同时需要设备端返回响应结果的场景。
IoT物联网平台基于MQTT协议制定了一套请求和响应的同步机制,无需改动MQTT协议即可实现同步通信。应用服务器通过POP API发起Rrpc调用,IoT设备端只需要在Timeout内,按照固定的格式回复Pub消息,服务端即可同步获取IoT设备端的响应结果。

具体流程如下:

1.2 Topic格式约定

请求:/sys/${productKey}/${deviceName}/rrpc/request/${messageId}
响应:/sys/${productKey}/${deviceName}/rrpc/**response**/**${messageId}**

$表示变量,每个设备不同
messageId为IoT平台生成的消息ID,
设备端回复responseTopic里的messageId要与requestTopic一致

示例:

设备端需要订阅:

/sys/${productKey}/${deviceName}/rrpc/request/+

运行中设备收到Topic:

/sys/PK100101/DN213452/rrpc/request/443859344534

收到消息后,在timeout时间内回复Topic:

/sys/PK100101/DN213452/rrpc/response/443859344534

2.同步调用RRPC示例

2.1 设备端代码

const mqtt = require('aliyun-iot-mqtt');
//设备属性
const options = require("./iot-device-config.json");
//建立连接
const client = mqtt.getAliyunIotMqttClient(options);

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){
        handleRrpc(topic, message)
    }
})

function handleRrpc(topic, message){
    topic = topic.replace('/request/','/response/');
    console.log("topic=" + topic)
    //普通Rrpc,响应payload自定义
    const payloadJson = {code:200,msg:"handle ok"};
    client.publish(topic, JSON.stringify(payloadJson));
}

2.2 服务端POP调用Rrpc

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

const options = require("./iot-ak-config.json");

//1.初始化client
const client = new RPCClient({
    accessKeyId: options.accessKey,
    secretAccessKey: options.accessKeySecret,
    endpoint: 'https://iot.cn-shanghai.aliyuncs.com',
    apiVersion: '2018-01-20'
});

const payload = {
  "msg": "hello Rrpc"
};

//2.构建request
const params = {
    ProductKey:"a1gMu82K4m2",
    DeviceName:"h5@nuwr5r9hf6l@1532088166923",
    RequestBase64Byte:new Buffer(JSON.stringify(payload)).toString("base64"),
    Timeout:3000
};

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

    console.log(JSON.stringify(response));
});

rrpc响应:

{
    "MessageId": "1037292594536681472",
    "RequestId": "D2150496-2A61-4499-8B2A-4B3EC4B2A432",
    "PayloadBase64Byte": "eyJjb2RlIjoyMDAsIm1zZyI6ImhhbmRsZSBvayJ9",
    "Success": true,
    "RrpcCode": "SUCCESS"
}

// PayloadBase64Byte 解码: {"code":200,"msg":"handle ok"}

3.物模型-服务同步调用InvokeThingService示例

注意:物模型 服务调用 接口InvokeThingService,不是Rrpc

设备订阅subTopic

注意:服务同步调用API是InvokeThingService

/sys/${productKey}/${deviceName}/rrpc/request/+

IoT云端下行的payload格式

{
 "id": 3536123,
 "version": "1.0",
 "params": {
   "入参key1": "入参value1",
   "入参key2": "入参value2"
 },
 "method": "thing.service.{tsl.service.identifier}"
}

设备响应replyTopic

/sys/${productKey}/${deviceName}/rrpc/response/request的消息Id

设备响应payload格式

{
 "id": 3536123,
 "code": 200,
 "data": {
   "出参key1": "出参value1",
   "出参key2": "出参value2"
 }
}

3.1 物模型-同步服务定义

3.2 设备端实现

const mqtt = require('aliyun-iot-mqtt');
//设备属性
const options = require("./iot-device-config.json");
//建立连接
const client = mqtt.getAliyunIotMqttClient(options);

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){
        handleRrpc(topic, message)
    }
})
/*
* 如果存在多个同步调用服务,需要通过payload里的method区分
*/
function handleRrpc(topic, message){

    topic = topic.replace('/request/','/response/');
    console.log("topic=" + topic)
    //物模型 同步服务调用,响应payload结构:
    const payloadJson = {
        id: Date.now(),
        code:200,
        data: {
            currentMode: Math.floor((Math.random() * 20) + 10)
        }
    }

    client.publish(topic, JSON.stringify(payloadJson));
}

注意:设备端响应的payload要满足物模型定义的出参结构

3.3 服务端POP 接口InvokeThingService

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

const options = require("./iot-ak-config.json");

//1.初始化client
const client = new RPCClient({
    accessKeyId: options.accessKey,
    secretAccessKey: options.accessKeySecret,
    endpoint: 'https://iot.cn-shanghai.aliyuncs.com',
    apiVersion: '2018-01-20'
});

const params = {
    ProductKey: "a1gMu82K4m2",
    DeviceName: "h5@nuwr5r9hf6l@1532088166923",
    Args: JSON.stringify({ "mode": "1" }),
    Identifier: "thing.service.setMode"
};

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

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

调用结果:

{
    "Data":{
        "Result": "{\"currentMode\":12}",
        "MessageId": "1536145625658"
    },
    "RequestId": "29FD78CE-D1FF-48F7-B0A7-BD52C142DD7F",
    "Success": true
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现连接亚马逊平台AWS IoT Core可以通过以下步骤: 1. 注册AWS账号并创建IoT Core服务。 2. 安装AWS IoT Device SDK for C++,该SDK提供了连接AWS IoT Core所需的功能和类库。 3. 在C++代码中使用AWS IoT Device SDK for C++提供的类库连接到AWS IoT Core,并实现消息的发布和订阅功能。 以下是一个简单的连接AWS IoT Core的C++代码示例: ```c++ #include <aws/iot/MqttClient.h> #include <aws/iot/MqttClientError.h> #include <aws/iot/MqttClientException.h> #include <aws/iot/model/ConnectRequest.h> #include <aws/iot/model/ConnectResponse.h> #include <aws/iot/model/PublishRequest.h> #include <aws/iot/model/PublishResponse.h> #include <aws/iot/model/SubscribeRequest.h> #include <aws/iot/model/SubscribeResponse.h> using namespace Aws::Iot; using namespace Aws::Iot::Model; // AWS IoT Core连接参数 const char* iotEndpoint = "your-iot-endpoint"; const char* clientId = "your-client-id"; const char* caFilePath = "path/to/ca/certificate"; const char* certFilePath = "path/to/client/certificate"; const char* keyFilePath = "path/to/client/private/key"; // 消息主题 const char* topic = "your-topic"; int main() { // 创建MQTT客户端 MqttClient mqttClient(clientId, iotEndpoint); // 配置MQTT客户端参数 mqttClient.SetCA(caFilePath); mqttClient.SetCert(certFilePath); mqttClient.SetKey(keyFilePath); // 连接到AWS IoT Core ConnectRequest connectRequest; auto connectOutcome = mqttClient.Connect(connectRequest); if (!connectOutcome.IsSuccess()) { // 连接失败处理 return 1; } // 发布消息 PublishRequest publishRequest; publishRequest.SetTopic(topic); publishRequest.SetPayload("Hello, AWS IoT Core!"); auto publishOutcome = mqttClient.Publish(publishRequest); if (!publishOutcome.IsSuccess()) { // 发布消息失败处理 return 2; } // 订阅消息 SubscribeRequest subscribeRequest; subscribeRequest.AddTopic(topic); auto subscribeOutcome = mqttClient.Subscribe(subscribeRequest); if (!subscribeOutcome.IsSuccess()) { // 订阅消息失败处理 return 3; } // 处理接收到的消息 while (true) { auto receivedMessage = mqttClient.ReceiveMessage(); if (receivedMessage.IsSuccess()) { // 处理消息 std::cout << "Received message: " << receivedMessage.GetMessage().GetPayload() << std::endl; } } return 0; } ``` 在以上示例中,我们使用AWS IoT Device SDK for C++提供的MqttClient类连接到AWS IoT Core,并通过PublishRequest类发布消息,通过SubscribeRequest类订阅消息,并使用ReceiveMessage()方法接收到消息。需要注意的是,以上示例仅为演示用途,实际应用中还需要进行异常处理和其他的业务逻辑处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值