IoT Hub を使用したクラウドからデバイスへのメッセージの送信 (Node.js)

Azure IoT Hub は、何百万ものデバイスとソリューション バックエンドの間に信頼性のある保護された双方向通信を確立するのに役立つ、フル マネージドのサービスです。

この記事で取り上げるテクニック:

  • ソリューション バックエンドから IoT Hub 経由で単一のデバイスに cloud-to-device (C2D) メッセージを送信する

  • cloud-to-device メッセージをデバイスで受信する

  • ソリューション バックエンドから、IoT Hub からデバイスに送信されたメッセージの配信確認 ("フィードバック") を要求する

注意

この記事で説明されている機能は、Standard レベルの IoT Hub でのみ使用できます。 Basic および Standard または Free レベルの IoT Hub の詳細については、ソリューションに適した IoT Hub のレベルの選択に関するページを参照してください。

この記事の最後に、次の 2 つの Node.js コンソール アプリを実行します。

  • simple_sample_device: Microsoft Azure IoT SDK for Node.js に含まれているサンプル デバイス アプリ。これは、IoT ハブに接続し、cloud-to-device メッセージを受信します。

  • SendCloudToDevice: IoT Hub 経由で cloud-to-device メッセージをデバイス アプリに送信し、その配信確認を受信します。

Note

IoT Hub には、Azure IoT device SDK を介して、多数のデバイス プラットフォームと言語 (C、Java、Python、JavaScript) に対する SDK サポートがあります。

cloud-to-device メッセージの詳細については、「IoT ハブから cloud-to-device メッセージを送信する」を参照してください。

前提条件

  • Azure サブスクリプション。 Azure サブスクリプションをお持ちでない場合は、開始する前に 無料アカウント を作成してください。

  • Azure サブスクリプション内の IoT ハブ。 ハブがまだない場合は、「IoT ハブの作成」の手順に従うことができます。

  • お使いの IoT ハブに登録されているデバイス。 デバイスをまだ登録していない場合は、Azure portal に登録します。

  • この記事では、Node.js 向けの Azure IoT SDK のサンプル コードを使用します。

    • GitHub から開発用マシンに SDK リポジトリをダウンロードするか、複製します。
    • 開発コンピューターに Node.js のバージョン 10.0.x 以上がインストールされていることを確認します。 開発環境を準備するでは、このアーティクルのために Node.js を Windows または Linux にインストールする方法が説明されています。
  • ポート 8883 がファイアウォールで開放されていることを確認してください。 この記事のデバイス サンプルでは、ポート 8883 を介して通信する MQTT プロトコルを使用しています。 このポートは、企業や教育用のネットワーク環境によってはブロックされている場合があります。 この問題の詳細と対処方法については、「IoT Hub への接続 (MQTT)」を参照してください。

デバイスの接続文字列を取得する

この記事では、デバイスをシミュレートするサンプル アプリを実行します。これは、IoT Hub 経由で送信された cloud-to-device メッセージを受信します。 Microsoft Azure IoT SDK for Node.js に含まれる simple_sample_device サンプル アプリは、IoT ハブに接続し、シミュレートされたデバイスとして動作します。 このサンプルは、IoT ハブに登録されているデバイスのプライマリ接続文字列を使用します。

IoT ハブに登録されているデバイスのプライマリ接続文字列を取得するには、次の手順に従います。

  1. Azure portal で、 [リソース グループ] を選択します。 ハブが配置されているリソース グループを選択し、リソースの一覧からハブを選択します。

  2. IoT ハブの左側ペインの [デバイス管理] の下にある [デバイス] を選択します。

  3. デバイスの一覧から、該当するデバイスを選択します。

  4. [プライマリ接続文字列] をコピーし、値を保存します。

    Azure portal で IoT ハブに登録されているデバイスからプライマリ接続文字列を取得する方法を示すスクリーンショット。

デバイス アプリでメッセージを受信する

このセクションでは、simple_sample_device サンプル デバイス アプリを実行して、IoT ハブ経由で送信された C2D メッセージを受信します。 新しいコマンド プロンプトを開き、Azure IoT Node.js SDK を解凍したフォルダーの下の azure-iot-sdk-node\device\samples\javascript フォルダーに移動します。 {Your device connection string} プレースホルダーの値を IoT ハブに登録されているデバイスからコピーしたデバイス接続文字列に置き換えて、次のコマンドを実行します。

set IOTHUB_DEVICE_CONNECTION_STRING={Your device connection string}
node simple_sample_device.js

サンプル デバイス アプリが正常に起動して IoT ハブに接続すると、次のように出力されます。

Client connected
Client connected
Client connected
Sending message: {"deviceId":"myFirstDevice","windSpeed":10.949952400617569,"temperature":26.0096515658525,"humidity":72.59398225838534}
Client connected
Client connected
send status: MessageEnqueued
Sending message: {"deviceId":"myFirstDevice","windSpeed":12.917649160180087,"temperature":27.336831253904613,"humidity":77.37300365434534}

この例では、メッセージが処理されたこと、およびデバイスのキューから安全に削除できることを IoT Hub に通知するために、デバイスで complete 関数が呼び出されます。 MQTT トランスポートを使用している場合は、complete の呼び出しは必要なく省略できます。 AMQP と HTTPS の場合は必要です。

MQTT ではなく AMQP と HTTPS を使用する場合、デバイスは次の処理もできます。

  • メッセージを破棄します。この場合、IoT Hub は将来の使用に備えてメッセージをデバイスのキュー内に保持します。
  • メッセージを拒否します。この場合、メッセージはデバイスのキューから完全に削除されます。

デバイスがメッセージを完了、破棄、または拒否することを妨げる問題が発生した場合、IoT Hub は一定のタイムアウト期間が経過した後で、メッセージの配信をキューに入れます。 このような理由から、同じメッセージを複数回受信した場合に生成される結果が毎回同じになるように、デバイス アプリ内のメッセージ処理ロジックをべき等にする必要があります。

cloud-to-device メッセージのライフサイクルと、IoT Hub が cloud-to-device メッセージを処理する方法の詳細については、「IoT ハブから cloud-to-device メッセージを送信する」を参照してください。

注意

トランスポートとして MQTT や AMQP の代わりに HTTPS を使用した場合、Client インスタンスが IoT Hub からのメッセージをチェックする頻度は低くなります (最小 25 分ごと)。 MQTT、AMQP、および HTTPS のサポートの相違点の詳細については、「cloud-to-device 通信に関するガイダンス」と「通信プロトコルの選択」を参照してください。

IoT ハブ接続文字列を取得する

この記事では、IoT Hub を介して cloud-to-device メッセージを送信するバックエンド サービスを作成します。 cloud-to-device メッセージを送信するサービスには、サービス接続のアクセス許可が必要となります。 既定では、どの IoT Hub も、このアクセス許可を付与する service という名前の共有アクセス ポリシーがある状態で作成されます。

サービス ポリシーの IoT Hub 接続文字列を取得するには、次の手順を実行します。

  1. Azure portal で、 [リソース グループ] を選択します。 ハブが配置されているリソース グループを選択し、リソースの一覧からハブを選択します。

  2. IoT ハブの左側のウィンドウで、 [共有アクセス ポリシー] を選択します。

  3. ポリシーの一覧から、サービス ポリシーを選択します。

  4. [プライマリ接続文字列] をコピーし、値を保存します。

Azure portal で IoT ハブから接続文字列を取得する方法を示すスクリーンショット。

IoT Hub の共有アクセス ポリシーとアクセス許可の詳細については、「アクセス制御とアクセス許可」を参照してください。

C2D メッセージを送信する

このセクションでは、クラウドからデバイスへのメッセージを、シミュレートされたデバイス アプリに送信する Node.js コンソール アプリを作成します。 デバイスからのデバイス ID と IoT ハブの接続文字列が必要です。

  1. 空のフォルダーを sendcloudtodevicemessageという名前で作成します。 コマンド プロンプトを開き、sendcloudtodevicemessage フォルダーに移動し、次のコマンドを実行してそのフォルダーに package.json ファイルを作成します。 npm コマンドによって表示される各プロンプトで Enter を押して、そのプロンプトの既定値をそのまま使用します。

    npm init
    
  2. コマンド プロンプトで、sendcloudtodevicemessage フォルダーに移動し、次のコマンドを実行して、azure-iothub パッケージをインストールします。

    npm install azure-iothub --save
    
  3. テキスト エディターを使用して、sendcloudtodevicemessage フォルダーに SendCloudToDeviceMessage.js ファイルを作成します。

  4. SendCloudToDeviceMessage.js ファイルの先頭に、次の require ステートメントを追加します。

    'use strict';
    
    var Client = require('azure-iothub').Client;
    var Message = require('azure-iot-common').Message;
    
  5. 次のコードを SendCloudToDeviceMessage.js ファイルに追加します。 プレースホルダー "{iot hub connection string}" と "{device ID}" の値は、先ほどメモした IoT ハブ接続文字列とデバイス ID に置き換えてください。

    var connectionString = '{iot hub connection string}';
    var targetDevice = '{device id}';
    
    var serviceClient = Client.fromConnectionString(connectionString);
    
  6. 操作結果をコンソールに出力するための次の関数を追加します。

    function printResultFor(op) {
      return function printResult(err, res) {
        if (err) console.log(op + ' error: ' + err.toString());
        if (res) console.log(op + ' status: ' + res.constructor.name);
      };
    }
    
  7. 配信フィードバック メッセージをコンソールに出力するための次の関数を追加します。

    function receiveFeedback(err, receiver){
      receiver.on('message', function (msg) {
        console.log('Feedback message:')
        console.log(msg.getData().toString('utf-8'));
      });
    }
    
  8. デバイスにメッセージを送信し、クラウドからデバイスへのメッセージが配信されたことの確認応答がデバイスからあったときにフィードバック メッセージを処理するための次のコードを追加します。

    serviceClient.open(function (err) {
      if (err) {
        console.error('Could not connect: ' + err.message);
      } else {
        console.log('Service client connected');
        serviceClient.getFeedbackReceiver(receiveFeedback);
        var message = new Message('Cloud to device message.');
        message.ack = 'full';
        message.messageId = "My Message ID";
        console.log('Sending message: ' + message.getData());
        serviceClient.send(targetDevice, message, printResultFor('send'));
      }
    });
    
  9. SendCloudToDeviceMessage.js ファイルを保存して閉じます。

アプリケーションの実行

これで、アプリケーションを実行する準備が整いました。

  1. コマンド プロンプトの azure-iot-sdk-node\device\samples\javascript フォルダーで次のコマンドを実行して、IoT Hub にテレメトリを送信し、cloud-to-device メッセージをリッスンします。

    node simple_sample_device.js
    

    シミュレーション済みデバイス アプリを実行する

  2. sendcloudtodevicemessage フォルダーからコマンド プロンプトで次のコマンドを実行し、クラウドからデバイスへのメッセージを送信して、配信確認のフィードバックを待機します。

    node SendCloudToDeviceMessage.js
    

    クラウドからデバイスへのコマンドを送信するアプリを実行する

    Note

    わかりやすくするために、この記事では再試行ポリシーは実装しません。 運用環境のコードでは、「一時的な障害の処理」の記事で推奨されているように、再試行ポリシー (指数関数的バックオフなど) を実装することをお勧めします。

次のステップ

この記事では、クラウドからデバイスへのメッセージを送受信する方法を学習しました。