MQTT.jsでIoT Hubに接続したときのメモです。
準備
とりあえずテストしたかったので無料プランを利用しました。デバイス作成までは以下が参考になりました。
認証はSAS(Shared Access Signature)を利用しました。
接続に必要な情報
AzureポータルからIoT Hubのリソースを表示し、必要な情報を取ってきます。(一部伏字にしています)
①ホスト名
②デバイスID
③主キー
- 概要ページ
- ①ホスト名は[IoT Hubの名前].azure-device.netというフォーマットです。
- デバイス管理 > デバイス > 詳細
- ②デバイスIDはデバイス作成時に指定したものです。
- ③主キーはデバイスの詳細から確認できます。
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 へのアクセスを制御する))をそのまま用いています。
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\"}"
}
}