无法使用node.js中的mqtt库监听azure iot hub事件

问题描述 投票:0回答:1
var mqtt = require("mqtt");
var CryptoJS = require("crypto-js");

var host = "iothub.azure-devices.net";
var deviceId = "test";
var sharedKey = "xxxSharedKeyxxx";


var publishtopic = "devices/" + deviceId + "/messages/devicebound/#";
var subscribetopic = "devices/" + deviceId + "/messages/events/";

function encodeUriComponentStrict(str) {
   return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {
   return "%" + c.charCodeAt(0).toString(16);
 });
 }

 function getSaSToken(hostName, deviceId, sharedKey) {
 var sr = encodeUriComponentStrict(hostName + "/devices/" + deviceId);
 var se = Math.round(new Date().getTime() / 1000) + 24 * 3600;
 var StringToSign = sr + "\n" + se;
 var sig = encodeUriComponentStrict(
   CryptoJS.HmacSHA256(
     StringToSign,
     CryptoJS.enc.Base64.parse(sharedKey)
   ).toString(CryptoJS.enc.Base64)
 );
 return "SharedAccessSignature sr=" + sr + "&sig=" + sig + "&se=" + se;
 }

 var client = mqtt.connect({
 hostname: "iothub.azure-devices.net",
 port: 8883,
 protocol: "mqtts",
 protocolVersion: 4,
 clientId:"test,
 username: "iothub.azure-devices.net/test/?api-version=2021-04-12",
 password: getSaSToken(host, deviceId, sharedKey),
 rejectUnauthorized: false,
 });

 client.on("connect", function (packet) {
 console.log(" sub mqtt connected!", packet);
 client.subscribe(subscribetopic);
 });

 client.on("reconnect", function () {
 console.log("mqtt reconnected!");
 });

 client.on("close", function (c) {
 console.log("mqtt closed!", c);
 });

  client.on("message", function (topic, message, packet) {
  var string = new TextDecoder("utf-8").decode(message);
  console.log("receive!", string);
 });


上面的代码随着物联网设备向 Azure Hub 发送消息而重新连接。并且我们无法获取设备在 Azure IoT Hub 上发布的数据。

我们使用了适用于node.js的“azure iot hub sdk”。使用它,我们可以轻松地向物联网设备发送和接收消息。

我们在上面的代码中订阅了“事件”主题,当设备发送消息时,代码将重新连接而不是订阅事件。

当我们发布到“devicebound”主题时,我们会在设备端收到 OsError。 我们的物联网设备正在使用 micro-python 代码。

node.js azure mqtt azure-iot-hub
1个回答
0
投票

az iot hub monitor-events
命令仅设计用于监控设备遥测和发送到 IoT 中心的消息。

由于您的代码当前没有消息发送部分,因此不会发送任何事件。

添加以下示例代码以发送遥测数据:

  const telemetryMessage = {
        temperature: 22,
        humidity: 60,
        timestamp: new Date().toISOString(),
    };
    console.log('Sending telemetry data:', telemetryMessage);
    client.publish(topic, JSON.stringify(telemetryMessage), { qos: 1 });

以下代码用于向 IoT 中心发送遥测消息并从 IoT 中心接收遥测消息:

我按照此链接使用MQTT与Azure IoT Hub进行通信。

const mqtt = require('mqtt');
const CryptoJS = require('crypto-js');

const deviceId = "<YourDeviceID>";
const deviceKey = "<YourDeviceKey>";
const iotHubHostName = "<YourIoTHubName>.azure-devices.net"; 
const topic = `devices/${deviceId}/messages/events/`; 
const clientId = `${deviceId}`;

function generateSasToken(uri, deviceKey, expiry = 3600) {
    const decodedKey = CryptoJS.enc.Base64.parse(deviceKey);
    const encodedUri = encodeURIComponent(uri);
    const expiryTime = Math.floor((Date.now() / 1000) + expiry);

    const stringToSign = `${encodedUri}\n${expiryTime}`;
    const hmac = CryptoJS.HmacSHA256(stringToSign, decodedKey);
    const signature = CryptoJS.enc.Base64.stringify(hmac);

    return `SharedAccessSignature sr=${encodedUri}&sig=${encodeURIComponent(signature)}&se=${expiryTime}`;
}

const mqttOptions = {
    clientId: clientId,
    username: `${iotHubHostName}/${deviceId}/?api-version=2018-06-30`, 
    password: generateSasToken(`devices/${deviceId}`, deviceKey), 
    clean: true,
    reconnectPeriod: 1000,
};

const client = mqtt.connect(`mqtts://${iotHubHostName}:8883`, mqttOptions);

client.on('connect', () => {
    console.log('Connected to Azure IoT Hub');

    const telemetryMessage = {
        temperature: 22,
        humidity: 60,
        timestamp: new Date().toISOString(),
    };
    console.log('Sending telemetry data:', telemetryMessage);
    client.publish(topic, JSON.stringify(telemetryMessage), { qos: 1 });

    const cloudToDeviceTopic = `devices/${deviceId}/messages/devicebound/#`; 
    client.subscribe(cloudToDeviceTopic, { qos: 1 }, (err) => {
        if (err) {
            console.error('Failed to subscribe:', err);
        } else {
            console.log('Subscribed to cloud-to-device messages');
        }
    });
});

client.on('message', (topic, message) => {
    console.log('Received message from IoT Hub:', topic, message.toString());
 
});
client.on('error', (err) => {
    console.error('Connection error:', err);
    client.end();
});

client.on('close', () => {
    console.log('Disconnected from Azure IoT Hub');
});

client.on('reconnect', () => {
    console.log('Reconnecting...');
});

输出: enter image description here

Azure CLI 输出:

要监视 Azure CLI 中的事件,请使用以下命令:

az iot hub monitor-events --output table --device-id mydevice --hub-name {YourIoTHubName}

enter image description here

发送的消息正文将显示在代码的 IoT Hub 收到的消息中。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.