当前位置: 首页 > 知识库问答 >
问题:

在Javascript中使用MQTT连接到Azure IotHub

吴鸿彩
2023-03-14

我还要求通过rejectunauthorization:false启用TLS/SSL(根据Microsoft Azure文档:https://docs.Microsoft.com/en-us/Azure/iot-hub/iot-hub-mqtt-support#tlsssl-configuration)(如https://github.com/mqttjs/mqtt.js#client上的mqtt.js文档所述)。

如何使用第三方MQTT库和SAS令牌通过Javascript进行连接?

这是Javascript代码的一个片段:

var MQTT = require("async-mqtt");

const deviceId = "<PUT_SOMETHING_HERE>";
const iotHubName = "<PUT_SOMETHING_HERE>";

const url = `${iotHubName}.azure-devices.net/${deviceId}/api-version=2016-11-14`;
const iotHubTopic = `devices/${deviceId}/messages/events/`

var client = MQTT.connect(`mqtts://${url}:8883`, {
  username: url,
  password: `SharedAccessSignature sr=${iotHubName}.azure-devices.net&sig=<COMBINATION_OF_PASSWORDS_URL_ENCODED>&se=<EPOCH_EXPIRY>&skn=<ACCESS_POLICY_NAME>`,
  rejectUnauthorized: false, // https://github.com/mqttjs/MQTT.js#client
});

// this is code from the MQTT.js example, but I don't even reach it
async function doStuff() {

    console.log("Starting");
    try {
        await client.publish(iotHubTopic, "It works!");
        // This line doesn't run until the server responds to the publish
        await client.end();
        // This line doesn't run until the client has disconnected without error
        console.log("Done");
    } catch (e){
        // Do something about it!
        console.log("Error while sending a message...");
        console.log(e.stack);
        process.exit();
    }
}

const ceremony = () => {
  return new Promise((resolve, reject) => {
      client.on("connect", doStuff);
      return resolve();
    })
    .then((stuff) => {
      console.log("Done?", stuff);
    })
    .catch((err) => {
      console.log("Err...", err);
      process.exit();
    });
}

ceremony();

输出如下:

Done? undefined
events.js:183
      throw er; // Unhandled 'error' event
      ^

Error: Connection refused: Not authorized
    at MqttClient._handleConnack (<PATH_TO_THE_JS_PROJECT>/node_modules/mqtt/lib/client.js:896:15)
    at MqttClient._handlePacket (<PATH_TO_THE_JS_PROJECT>/node_modules/mqtt/lib/client.js:332:12)
    at work (<PATH_TO_THE_JS_PROJECT>/node_modules/mqtt/lib/client.js:274:12)
    at Writable.writable._write (<PATH_TO_THE_JS_PROJECT>/node_modules/mqtt/lib/client.js:284:5)
    at doWrite (<PATH_TO_THE_JS_PROJECT>/node_modules/mqtt/node_modules/readable-stream/lib/_stream_writable.js:428:64)
    at writeOrBuffer (<PATH_TO_THE_JS_PROJECT>/node_modules/mqtt/node_modules/readable-stream/lib/_stream_writable.js:417:5)
    at Writable.write (<PATH_TO_THE_JS_PROJECT>/node_modules/mqtt/node_modules/readable-stream/lib/_stream_writable.js:334:11)
    at TLSSocket.ondata (_stream_readable.js:639:20)
    at emitOne (events.js:116:13)
    at TLSSocket.emit (events.js:211:7)

共有1个答案

鞠侯林
2023-03-14

是的,Azure IoT Hub支持MQTT,您可以使用MQTT协议直接与IoT Hub连接,并使用文档化的主题名称和主题过滤器将主题发布/订阅为发送/接收消息。我已经修改了上面的代码,它工作得很好。

var MQTT = require("async-mqtt");

const deviceId = "{the device name}";
const iotHubName = "{your iot hub name}";
const userName = `${iotHubName}.azure-devices.net/${deviceId}/api-version=2016-11-14`;
const iotHubTopic = `devices/${deviceId}/messages/events/`;

var client = MQTT.connect(`mqtts://${iotHubName}.azure-devices.net:8883`, {
  keepalive: 10,
  clientId: deviceId,
  protocolId: 'MQTT',
  clean: false,
  protocolVersion: 4,
  reconnectPeriod: 1000,
  connectTimeout: 30 * 1000,
  username: userName,
  password: "{SAS Token}",
  rejectUnauthorized: false, 
});

// this is code from the MQTT.js example, but I don't even reach it
async function doStuff() {

    console.log("Starting");
    try {
        await client.publish(iotHubTopic, "It works!");
        // This line doesn't run until the server responds to the publish
        await client.end();
        // This line doesn't run until the client has disconnected without error
        console.log("Done");
    } catch (e){
        // Do something about it!
        console.log("Error while sending a message...");
        console.log(e.stack);
        process.exit();
    }
}

const ceremony = () => {
  return new Promise((resolve, reject) => {
      client.on("connect", doStuff);
      return resolve();
    })
    .then((stuff) => {
      console.log("Done?", stuff);
    })
    .catch((err) => {
      console.log("Err...", err);
      process.exit();
    });
}

ceremony();

在代码中,您需要注意:

  1. 在连接选项中使用IoT集线器中的设备ID作为clientId;
  2. 使用mqtts协议;
  3. 对于username选项,请使用{iothubhostname}/{device_id}/api-version=2016-11-14,其中{iothubhostname}是IoT集线器的完整CName。
  4. 对于密码字段,请使用SAS令牌。可以使用设备资源管理器获取SAS令牌。SAS令牌必须使用涉及权限的策略生成:“注册表写”、“服务连接”和“设备连接”(少于这三个权限的组合可能有效,但提供“注册表写”肯定不够)。
 类似资料:
  • 我试图使用Firebase的云函数使Dialogflow意图导致发布MQTT消息。我已经设法获得了我需要的数据,但我仍然无法完成的是: 建立到MQTT代理的连接; 发布到所述代理。 由于第二个需要前者,这还不是我关心的。

  • 我正试图通过MQTT发布服务器发布事件。在提供程序URL中提到了tls://URL:port 当我试图执行时,它会给出以下错误:。我使用的是apache jmeter 5.0和MQTT jar版本:mqtt-jmeter-0.0.1-snapshot java.lang.IllegalArgumentException:tls://...:1887 at org.eclipse.paho.clie

  • 是否可以在JavaScript/Ajax/jQuery中使用oAuth与Github连接 谢谢

  • “事件” 我试图通过使用从Kii Cloud MQTT获得的endpoint建立连接,但返回了以下错误。 ※我将paho用于MQTT客户端。 ·我分离出问题的原因。(客户端或服务器端) →我运行paho的示例代码,它能够成功地连接到代理(test.mosquitto.org:8080)。 ·Ping通信确认 服务器端:Kii云 非常感谢。

  • 断开mqtt连接,前提是必须已经通过Iot_id,Iot_pwd建立过一次mqtt连接。 请求方式: "|4|1|4|\r" 返回值: "|4|1|4|1|\r" 断开成功 "|4|1|4|2|\r" 断开失败 Arduino样例: softSerial.print("|4|1|4|\r");