日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

mqtt js 中乱码_mqtt之上RRPC同步调用实战

發布時間:2024/10/12 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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.初始化client
    const?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/topic
    payloadJson=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同步调用实战的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。