Google IOT Core連接設備MQTT客戶端

實現Google IOT Core核心連接到物聯網設備(MQTT)具體過程:

  1. 通過函數API創建返回公/私鑰值,保存到雲存儲;(上一篇有詳細講解如何調用API公/私鑰)。
  2. 讀取雲存儲公/私鑰,判斷是否註冊以及是否過期,如果過期,再次註冊API公/私鑰。
  3. 檢查公/私鑰值是否正確導入項目,RSA256或RSA_X256。
  4. 私鑰創建JWT身份驗證。
  5. 通過JWT以及私鑰串與設備名連接到MQTT。

一:導入項目mqtt包(Nodejs)

1.package.json

"jsonwebtoken": "^8.5.1",
 "mqtt": "^3.0.0",

2.mqtt.js

'use strict';

// [START iot_mqtt_include]
const fs = require('fs');
const jwt = require('jsonwebtoken');
const mqtt = require('mqtt');
// [END iot_mqtt_include]
// The initial backoff time after a disconnection occurs, in seconds.
const MINIMUM_BACKOFF_TIME = 1;

// The maximum backoff time before giving up, in seconds.
const MAXIMUM_BACKOFF_TIME = 32;

// Whether to wait with exponential backoff before publishing.
let shouldBackoff = false;

// The current backoff time.
let backoffTime = 1;

// Whether an asynchronous publish chain is in progress.
let publishChainInProgress = false;

console.log('Google Cloud IoT Core MQTT example.');

const deviceId = "你的設備名";
const registryId = "註冊表";
const projectId = "項目名";
const region = "us-central1";//區域
const algorithm = "RS256";//密鑰類型
const privateKeyFile = "rsa_private.pem";//文件
const mqttBridgeHostname = "mqtt.googleapis.com";
const mqttBridgePort = "443";//或者8883(國外)
const messageType = "events";
const numMessages = "50";
const tokenExpMins = "20";
const gatewayId = "my-region-001";//網關id
const clientDuration = "6000";

//創建JWT函數
const createJwt = (projectId, privateKeyFile, algorithm) => {

    const token = {
        iat: parseInt(Date.now() / 1000),
        exp: parseInt(Date.now() / 1000) + 20 * 60, // 20 minutes
        aud: projectId,
    };
    const privateKey = fs.readFileSync(privateKeyFile);
    console.log("privateKey:",privateKey.toString());
    console.log("createJwt yes:",jwt.sign(token, privateKey, {algorithm: algorithm}));
    return jwt.sign(token, privateKey, {algorithm: algorithm});

};

3.MQTT連接的函數實現:

//mqtt的連接
const mqttDeviceDemo = (
    deviceId,
    registryId,
    projectId,
    region,
    algorithm,
    privateKeyFile,
    mqttBridgeHostname,
    mqttBridgePort,
    messageType,
    numMessages
) => {
    // The mqttClientId is a unique string that identifies this device. For Google
    // Cloud IoT Core, it must be in the format below.
    const mqttClientId = `projects/${projectId}/locations/${region}/registries/${registryId}/devices/${deviceId}`;
    console.log("000++",mqttClientId);
    const connectionArgs = {
        host: mqttBridgeHostname,
        port: mqttBridgePort,
        clientId: mqttClientId,
        username: 'unused',
        password: createJwt(projectId, privateKeyFile, algorithm),
        protocol: 'mqtts',
        secureProtocol: 'TLSv1_2_method',
    };
    console.log("001++",connectionArgs);

    // Create a client, and connect to the Google MQTT bridge.
    const iatTime = parseInt(Date.now() / 1000);
    const client = mqtt.connect(connectionArgs);

    client.subscribe(`/devices/${deviceId}/config`, {qos: 1});
    client.subscribe(`/devices/${deviceId}/commands/#`, {qos: 0});
    console.log('client002======',client);
    const mqttTopic = `/devices/${deviceId}/${messageType}`;
    console.log('mqttTopic003======',mqttTopic);
    client.on('connect', success => {
        console.log('connect004');
        if (!success) {
            console.log('Client not connected005...');
        } else if (!publishChainInProgress) {
            console.log('connected...666999999');
            //publishAsync(mqttTopic, client, iatTime, 1, numMessages, connectionArgs);
        }
    });

    client.on('close', () => {
        console.log('close');
        shouldBackoff = true;
    });

    client.on('error', err => {
        console.log('error', err);
    });

    client.on('message', (topic, message) => {
        let messageStr = 'Message received: ';
        if (topic === `/devices/${deviceId}/config`) {
            messageStr = 'Config message received: ';
        } else if (topic.startsWith(`/devices/${deviceId}/commands`)) {
            messageStr = 'Command message received: ';
        }

        messageStr += Buffer.from(message, 'base64').toString('ascii');
        console.log(messageStr);
    });

    client.on('packetsend', () => {
        // Note: logging packet send is very verbose
    });

    // Once all of the messages have been published, the connection to Google Cloud
    // IoT will be closed and the process will exit. See the publishAsync method.
    // [END iot_mqtt_run]
};

4.調用雲函數功能:

exports.tmwrilmqtt_conent = async (req,res) => {

    mqttDeviceDemo(
        deviceId,
        registryId,
        projectId,
        region,
        algorithm,
        privateKeyFile,
        mqttBridgeHostname,
        mqttBridgePort,
        messageType,
        numMessages
    );
}

二:部署到Google Function雲函數,可通過PostMan進行調試。

1.cd~ 項目名
2.gcloud functions deploy (函數的名稱) --runtime nodejs8 --trigger-http

三:調試樣本:

在這裏插入圖片描述在這裏插入圖片描述

四:通過命令發佈消息到設備

const SendDevice = async(
    projectId,
    cloudRegion,
    registryId,
    deviceId,
    sendevicedata,
    res
) => {
    const iot = require('@google-cloud/iot');
    const client = new iot.v1.DeviceManagerClient({
        // optional auth parameters.
    });
    const binaryData = Buffer.from(sendevicedata).toString('base64');
    const formattedName = client.devicePath(projectId,cloudRegion,registryId,deviceId);
   // const binaryData = Buffer.from('wo shi ming ling device 001');
    const request = {
        name:formattedName,
        binaryData:binaryData,
    };
    client.sendCommandToDevice(request)
        .then(responses => {
            const response = responses[0];
            res.send(response);
            // doThingsWith(response)
        })
        .catch(err => {
            console.error(err);
            res.send(err);
        });
}

在這裏插入圖片描述
在這裏插入圖片描述

五:MQTT連接設備錯誤排除:

  • Error: Connection refused: Not authorized at

解決辦法:仔細檢查客戶端的私鑰Key,是否是RSA256官方創建的,並不是帶X509。
在這裏插入圖片描述

MQTT連接Google IOT Core設備源碼

MQTT連接設備講解到此爲止,如果依然還有不懂的,可以留言諮詢,謝謝希望能幫助到您!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章