LoginSignup
2
0

More than 1 year has passed since last update.

SDKを使わずにNode.jsからAzure IoT HubへMQTT接続する

Posted at

MQTT.jsでIoT Hubに接続したときのメモです。

準備

とりあえずテストしたかったので無料プランを利用しました。デバイス作成までは以下が参考になりました。

認証はSAS(Shared Access Signature)を利用しました。

接続に必要な情報

AzureポータルからIoT Hubのリソースを表示し、必要な情報を取ってきます。(一部伏字にしています)

①ホスト名
②デバイスID
③主キー

  • 概要ページ
    • ①ホスト名は[IoT Hubの名前].azure-device.netというフォーマットです。

iothub-info1.png

  • デバイス管理 > デバイス > 詳細
    • ②デバイスIDはデバイス作成時に指定したものです。
    • ③主キーはデバイスの詳細から確認できます。

iothub-info2.png

Node.jsパッケージのインストール

mqttとcryptをインストールします。

$ npm init
$ npm install mqtt crypto

テスト

コード

トピックをPublishするプログラムです。
動かす際はHOST・DEVICE_ID・PRIMARY_KEYを前述の情報に書き換えてください。
トピック名はデフォルトで「devices/[デバイスID]/messages/events/」が使えます。
コード内のgenerateSasTokenメソッドはAzureのサンプルコード([https://learn.microsoft.com/ja-jp/azure/iot-hub/iot-hub-dev-guide-sas?tabs=node](Shared Access Signature を使用して IoT Hub へのアクセスを制御する))をそのまま用いています。

publisher.js
const mqtt = require('mqtt');
const crypto = require('crypto');

//接続に必要な情報
const HOST = ホスト名;  //①ホスト名
const DEVICE_ID = 'dev0';  //②デバイスID
const PRIMARY_KEY = 主キー;  //③主キー

const API_VERSION = '2021-04-12'; //APIバージョン

//SASトークンを生成するメソッド(Azure公式のサンプルより)
const generateSasToken = (resourceUri, signingKey, policyName, expiresInMins) => {
  resourceUri = encodeURIComponent(resourceUri);

  // Set expiration in seconds
  var expires = (Date.now() / 1000) + expiresInMins * 60;
  expires = Math.ceil(expires);
  var toSign = resourceUri + '\n' + expires;

  // Use crypto
  var hmac = crypto.createHmac('sha256', Buffer.from(signingKey, 'base64'));
  hmac.update(toSign);
  var base64UriEncoded = encodeURIComponent(hmac.digest('base64'));

  // Construct authorization string
  var token = "SharedAccessSignature sr=" + resourceUri + "&sig="
    + base64UriEncoded + "&se=" + expires;
  if (policyName) token += "&skn=" + policyName;
  return token;
};

//SASトークンを生成
const token = generateSasToken(HOST, PRIMARY_KEY, null, 60);
//MQTT接続のオプション
const mqttOptions =   {
  username: `${HOST}/${DEVICE_ID}/api-version=${API_VERSION}`,
  password: token,
  clientId: DEVICE_ID
}
//接続
const mqttClient = mqtt.connect(`mqtts://${HOST}:8883`, mqttOptions);
//接続できたらPublishして終了
mqttClient.on('connect', () => {
  console.log('connected to MQTT Broker');
  mqttClient.publish('devices/dev0/messages/events/', JSON.stringify({msg: 'hello'}), { qos: 1 });
  mqttClient.end();
});
//エラー処理
mqttClient.on('error', (err) => {
  console.error(err);
});

動作確認

上記のプログラムを実行するとトピックがPublishされます。

$ node publisher.js

PublishしたトピックがIoT Hubで受信できているかはAzure CLIで確認しました。
成功すると以下のように受信した内容が表示されます。

> az iot hub monitor-events --hub-name ${IoT Hubの名前}
Starting event monitor, use ctrl-c to stop...
{
    "event": {
        "origin": "dev0",
        "module": "",
        "interface": "",
        "component": "",
        "payload": "{\"msg\":\"hello\"}"
    }
}
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0