MQTT プロトコルを使用した IoT Hub との通信Communicate with your IoT hub using the MQTT protocol

IoT Hub により、デバイスは、以下を使用して IoT Hub デバイス エンドポイントと通信できます。IoT Hub enables devices to communicate with the IoT Hub device endpoints using:

  • ポート 8883 上の MQTT v3.1.1MQTT v3.1.1 on port 8883
  • ポート 443 で WebSocket を介して MQTT v3.1.1MQTT v3.1.1 over WebSocket on port 443.

IoT Hub はフル機能の MQTT ブローカーではないため、MQTT v3.1.1 標準で指定されているすべての動作をサポートしているわけではありません。IoT Hub is not a full-featured MQTT broker and does not support all the behaviors specified in the MQTT v3.1.1 standard. この記事では、サポートされている MQTT 動作を使用して、デバイスと IoT Hub の通信を行う方法について説明します。This article describes how devices can use supported MQTT behaviors to communicate with IoT Hub.

注意

この記事で言及されている一部の機能 (cloud-to-device メッセージング、デバイス ツイン、デバイス管理など) は、IoT Hub の Standard レベルだけで使用することができます。Some of the features mentioned in this article, like cloud-to-device messaging, device twins, and device management, are only available in the standard tier of IoT Hub. IoT Hub の Basic レベルおよび Standard レベルの詳細については、適切な IoT Hub レベルの選び方に関するページを参照してください。For more information about the basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

IoT Hub でのすべてのデバイス通信は、TLS/SSL を使用してセキュリティで保護する必要があります。All device communication with IoT Hub must be secured using TLS/SSL. そのため、IoT Hub では、ポート 1883 経由のセキュリティで保護されていない接続はサポートしません。Therefore, IoT Hub doesn't support non-secure connections over port 1883.

IoT Hub への接続Connecting to IoT Hub

デバイスでは、MQTT プロトコルを使用し、次のいずれかのオプションを利用して IoT ハブに接続できます。A device can use the MQTT protocol to connect to an IoT hub using any of the following options.

  • Azure IoT SDK にあるライブラリ。Libraries in the Azure IoT SDKs.
  • 直接的な MQTT プロトコル。The MQTT protocol directly.

MQTT ポート (8883) は、多くの企業や教育用のネットワーク環境ではブロックされています。The MQTT port (8883) is blocked in many corporate and educational networking environments. ファイアウォールでポート 8883 を開けない場合は、MQTT over WebSocket を使用することをお勧めします。If you can't open port 8883 in your firewall, we recommend using MQTT over Web Sockets. MQTT over WebSocket は、ほとんどの場合はネットワーク環境で開放されているポート 443 を介して通信します。MQTT over Web Sockets communicates over port 443, which is almost always open in networking environments. Azure IoT SDK を使用しているときに MQTT プロトコルと MQTT over WebSocket プロトコルを指定する方法については、「デバイス SDK の使用」を参照してください。To learn how to specify the MQTT and MQTT over Web Sockets protocols when using the Azure IoT SDKs, see Using the device SDKs.

デバイス SDK の使用Using the device SDKs

MQTT プロトコルをサポートするデバイス SDK は、Java、Node.js、C、C#、および Python に対応しています。Device SDKs that support the MQTT protocol are available for Java, Node.js, C, C#, and Python. デバイス SDK では、標準的な IoT Hub 接続文字列を使用して、IoT ハブへの接続を確立します。The device SDKs use the standard IoT Hub connection string to establish a connection to an IoT hub. MQTT プロトコルを使用するには、クライアント プロトコル パラメーターを MQTTに設定する必要があります。To use the MQTT protocol, the client protocol parameter must be set to MQTT. また、クライアント プロトコル パラメーターで MQTT over Web Sockets を指定することもできます。You can also specify MQTT over Web Sockets in the client protocol parameter. デバイス SDK は既定では、CleanSession フラグを 0 に設定して IoT ハブに接続し、IoT ハブとのメッセージ交換には QoS 1 を使用します。By default, the device SDKs connect to an IoT Hub with the CleanSession flag set to 0 and use QoS 1 for message exchange with the IoT hub. メッセージ交換を高速にすために QoS 0 を構成することはできますが、配信が保証されず、確認応答がないことに注意する必要があります。While it's possible to configure QoS 0 for faster message exchange, you should note that the delivery isn't guaranteed nor acknowledged. このため、QoS 0 は "ファイア アンド フォーゲット" と呼ばれることがよくあります。For this reason, QoS 0 is often referred as "fire and forget".

デバイスは、IoT ハブに接続されると、デバイス SDK によって、IoT ハブとのメッセージの交換を可能にするメソッドが提供されます。When a device is connected to an IoT hub, the device SDKs provide methods that enable the device to exchange messages with an IoT hub.

次の表では、サポートされている各言語のコード サンプルへのリンクを提供すると共に、MQTT プロトコルまたは MQTT over WebSocket プロトコルを使用して IoT Hub への接続を確立するために使用するパラメーターを示します。The following table contains links to code samples for each supported language and specifies the parameter to use to establish a connection to IoT Hub using the MQTT or the MQTT over Web Sockets protocol.

LanguageLanguage MQTT プロトコルのパラメーターMQTT protocol parameter MQTT over WebSocket プロトコルのパラメーターMQTT over Web Sockets protocol parameter
Node.jsNode.js azure-iot-device-mqtt.Mqttazure-iot-device-mqtt.Mqtt azure-iot-device-mqtt.MqttWsazure-iot-device-mqtt.MqttWs
JavaJava IotHubClientProtocol.MQTTIotHubClientProtocol.MQTT IotHubClientProtocol.MQTT_WSIotHubClientProtocol.MQTT_WS
CC MQTT_ProtocolMQTT_Protocol MQTT_WebSocket_ProtocolMQTT_WebSocket_Protocol
C#C# TransportType.MqttTransportType.Mqtt MQTT が失敗した場合、TransportType.Mqtt は MQTT over WebSocket にフォールバックします。TransportType.Mqtt falls back to MQTT over Web Sockets if MQTT fails. MQTT over WebSocket のみを指定するには、TransportType.Mqtt_WebSocket_Only を使用しますTo specify MQTT over Web Sockets only, use TransportType.Mqtt_WebSocket_Only
PythonPython 既定で MQTT をサポートしますSupports MQTT by default 呼び出しに websockets=True を追加してクライアントを作成しますAdd websockets=True in the call to create the client

次のフラグメントでは、Azure IoT Node.js SDK を使用しているときに MQTT over WebSocket プロトコルを指定する方法を示しています。The following fragment shows how to specify the MQTT over Web Sockets protocol when using the Azure IoT Node.js SDK:

var Client = require('azure-iot-device').Client;
var Protocol = require('azure-iot-device-mqtt').MqttWs;
var client = Client.fromConnectionString(deviceConnectionString, Protocol);

次のフラグメントでは、Azure IoT Python.js SDK を使用しているときに MQTT over WebSocket プロトコルを指定する方法を示しています。The following fragment shows how to specify the MQTT over Web Sockets protocol when using the Azure IoT Python SDK:

from azure.iot.device.aio import IoTHubDeviceClient
device_client = IoTHubDeviceClient.create_from_connection_string(deviceConnectionString, websockets=True)

既定のキープアライブ タイムアウトDefault keep-alive timeout

クライアント/IoT Hub 接続を確実に存続させるために、サービスとクライアントは、どちらもキープアライブ ping を定期的に相手に送信します。In order to ensure a client/IoT Hub connection stays alive, both the service and the client regularly send a keep-alive ping to each other. IoT SDK を使用しているクライアントは、次の表に定義されている間隔でキープアライブを送信します。The client using IoT SDK sends a keep-alive at the interval defined in this table below:

LanguageLanguage 既定のキープアライブ間隔Default keep-alive interval 構成可能Configurable
Node.jsNode.js 180 秒180 seconds いいえNo
JavaJava 230 秒230 seconds いいえNo
CC 240 秒240 seconds はいYes
C#C# 300 秒300 seconds はいYes
PythonPython 60 秒60 seconds いいえNo

MQTT 仕様に従って、IoT Hub のキープアライブ ping の間隔は、クライアントのキープアライブ値の 1.5 倍です。Following MQTT spec, IoT Hub's keep-alive ping interval is 1.5 times the client keep-alive value. ただし、IoT Hub では、すべての Azure サービスは Azure ロードバランサーの TCP アイドル タイムアウト (29.45 分) にバインドされているため、サーバー側のタイムアウトの最大値は 29.45 分 (1,767 秒) に制限されます。However, IoT Hub limits the maximum server-side timeout to 29.45 minutes (1767 seconds) because all Azure services are bound to the Azure load balancer TCP idle timeout, which is 29.45 minutes.

たとえば、Java SDK を使用しているデバイスでは、キープアライブ ping が送信された後、ネットワーク接続が失われます。For example, a device using the Java SDK sends the keep-alive ping then loses network connectivity. 230 秒後、デバイスはオフラインになっているため、キープアライブ ping は失敗します。230 seconds later, the device misses the keep-alive ping because it's offline. ただし、IoT Hub では、接続はすぐに閉じられるわけではありません。さらに (230 * 1.5) - 230 = 115 秒間待機した後、エラー 404104 DeviceConnectionClosedRemotely でデバイスが切断されます。However, IoT Hub doesn't close the connection immediately - it waits another (230 * 1.5) - 230 = 115 seconds before disconnecting the device with the error 404104 DeviceConnectionClosedRemotely.

設定できるクライアントのキープアライブの最大値は、1767 / 1.5 = 1177 秒です。The maximum client keep-alive value you can set is 1767 / 1.5 = 1177 seconds. すべてのトラフィックで、キープアライブがリセットされます。Any traffic will reset the keep-alive. たとえば、SAS トークンの正常な更新によって、キープアライブがリセットされます。For example, a successful SAS token refresh resets the keep-alive.

デバイス アプリの AMQP から MQTT への移行Migrating a device app from AMQP to MQTT

デバイス SDK を使用している場合、AMQP から MQTT に使用を切り替えるには、前述のようにクライアントの初期化時にプロトコル パラメーターを変更する必要があります。If you are using the device SDKs, switching from using AMQP to MQTT requires changing the protocol parameter in the client initialization as stated previously.

これを行う際は、次の項目をご確認ください。When doing so, make sure to check the following items:

  • AMQP では、MQTT 接続を終了するときに、多くの条件のエラーが返されます。AMQP returns errors for many conditions, while MQTT terminates the connection. そのため、例外処理のロジックを一部変更する必要が生じることがあります。As a result your exception handling logic might require some changes.

  • MQTT は、クラウドからデバイスへのメッセージを受信するときの "拒否" 操作をサポートしていません。MQTT does not support the reject operations when receiving cloud-to-device messages. バックエンド アプリではデバイス アプリから応答を受信する必要がある場合、ダイレクト メソッドの使用を検討してください。If your back-end app needs to receive a response from the device app, consider using direct methods.

  • Python SDK では AMQP は サポートされていません。AMQP is not supported in the Python SDK

MQTT プロトコルの直接使用 (デバイスとして)Using the MQTT protocol directly (as a device)

デバイスでデバイス SDK を使用できない場合でも、MQTT プロトコルをポート 8883 で使用して、デバイスをパブリックのデバイス エンドポイントに接続できます。If a device cannot use the device SDKs, it can still connect to the public device endpoints using the MQTT protocol on port 8883. CONNECT パケットの場合、デバイスでは次の値を使用する必要があります。In the CONNECT packet, the device should use the following values:

  • ClientId フィールドには、deviceId を使用します。For the ClientId field, use the deviceId.

  • [Usename] フィールドには、{iothubhostname}/{device_id}/?api-version=2018-06-30 を使用します。{iothubhostname} は IoT Hub の完全な CName です。For the Username field, use {iothubhostname}/{device_id}/?api-version=2018-06-30, where {iothubhostname} is the full CName of the IoT hub.

    たとえば、IoT Hub の名前が contoso.azure-devices.net であり、デバイスの名前が MyDevice01 であるとすると、Username フィールドの内容は 次のようになります。For example, if the name of your IoT hub is contoso.azure-devices.net and if the name of your device is MyDevice01, the full Username field should contain:

    contoso.azure-devices.net/MyDevice01/?api-version=2018-06-30

  • [Password] フィールドには、SAS トークンを使用します。For the Password field, use a SAS token. SAS トークンの形式は、HTTPS プロトコルや AMQP プロトコルの場合と同じです。The format of the SAS token is the same as for both the HTTPS and AMQP protocols:

    SharedAccessSignature sig={signature-string}&se={expiry}&sr={URL-encoded-resourceURI}

    注意

    X.509 証明書の認証を使用する場合は、SAS トークン パスワードは不要です。If you use X.509 certificate authentication, SAS token passwords are not required. 詳細については、「Azure IoT Hub での X.509 セキュリティの設定」を参照し、以下のコードの説明に従ってください。For more information, see Set up X.509 security in your Azure IoT Hub and follow code instructions below.

    SAS トークンの生成方法について詳しくは、IoT Hub のセキュリティ トークンの使用に関するページにあるデバイスのセクションをご覧ください。For more information about how to generate SAS tokens, see the device section of Using IoT Hub security tokens.

    テスト時には、クロスプラットフォームの Visual Studio Code 用 Azure IoT Tools または CLI 拡張機能コマンド az iot hub generate-sas-token を使用して SAS トークンを簡単に生成し、コピーして自分のコードに貼り付けることができます。When testing, you can also use the cross-platform Azure IoT Tools for Visual Studio Code or the CLI extension command az iot hub generate-sas-token to quickly generate a SAS token that you can copy and paste into your own code:

Azure IoT Tools の場合For Azure IoT Tools

  1. Visual Studio Code の左下隅にある [Azure IoT ハブ デバイス] タブを展開します。Expand the AZURE IOT HUB DEVICES tab in the bottom left corner of Visual Studio Code.

  2. デバイスを右クリックし、 [Generate SAS Token for Device](デバイスの SAS トークンの生成) を選択します。Right-click your device and select Generate SAS Token for Device.

  3. [期限] を設定し、Enter キーを押します。Set expiration time and press 'Enter'.

  4. SAS トークンが作成され、クリップボードにコピーされます。The SAS token is created and copied to clipboard.

    生成される SAS トークンは、次のような構成になります。The SAS token that's generated has the following structure:

    HostName={your hub name}.azure-devices.net;DeviceId=javadevice;SharedAccessSignature=SharedAccessSignature sr={your hub name}.azure-devices.net%2Fdevices%2FMyDevice01%2Fapi-version%3D2016-11-14&sig=vSgHBMUG.....Ntg%3d&se=1456481802

    MQTT を使用して接続するための [Password] フィールドとして使用されるこのトークンの一部は次のようになります。The part of this token to use as the Password field to connect using MQTT is:

    SharedAccessSignature sr={your hub name}.azure-devices.net%2Fdevices%2FMyDevice01%2Fapi-version%3D2016-11-14&sig=vSgHBMUG.....Ntg%3d&se=1456481802

MQTT の接続パケットおよび切断パケットの場合、IoT Hub は 操作の監視 チャネルでイベントを発行します。For MQTT connect and disconnect packets, IoT Hub issues an event on the Operations Monitoring channel. このイベントには、接続の問題をトラブルシューティングするために役立つ追加情報があります。This event has additional information that can help you to troubleshoot connectivity issues.

デバイス アプリは、CONNECT パケットに Will メッセージを指定できます。The device app can specify a Will message in the CONNECT packet. また、デバイス アプリは、devices/{device_id}/messages/events/ または devices/{device_id}/messages/events/{property_bag}Will トピック名として使用することで、テレメトリ メッセージとして転送される Will メッセージ を定義する必要があります。The device app should use devices/{device_id}/messages/events/ or devices/{device_id}/messages/events/{property_bag} as the Will topic name to define Will messages to be forwarded as a telemetry message. この場合、ネットワーク接続が閉じているが、DISCONNECT パケットがデバイスからまだ受信されていなければ、IoT Hub は、CONNECT パケットで提供される Will メッセージをテレメトリ チャネルに送信します。In this case, if the network connection is closed, but a DISCONNECT packet was not previously received from the device, then IoT Hub sends the Will message supplied in the CONNECT packet to the telemetry channel. テレメトリ チャネルは、既定のイベント エンドポイントにすることも、IoT Hub ルーティングで定義されるカスタム エンドポイントにすることもできます。The telemetry channel can be either the default Events endpoint or a custom endpoint defined by IoT Hub routing. メッセージには iothub-MessageType プロパティが含まれており、その値には Will が割り当てられています。The message has the iothub-MessageType property with a value of Will assigned to it.

Azure IoT C SDK を使用せずに MQTT を使用した C コードの例An example of C code using MQTT without Azure IoT C SDK

このリポジトリでは、Azure IoT C SDK を使用せずに、IoT ハブでテレメトリ メッセージを送信し、イベントを受信する方法を示す C/C++ のデモ プロジェクトをいくつか紹介します。In this repository, you'll find a couple of C/C++ demo projects showing how to send telemetry messages, receive events with an IoT hub without using the Azure IoT C SDK.

これらのサンプルでは、Eclipse Mosquitto ライブラリを使用して、IoT ハブ に実装されている MQTT ブローカーにメッセージを送信します。These samples use the Eclipse Mosquitto library to send message to the MQTT Broker implemented in the IoT hub.

このリポジトリには、次のものが含まれます。This repository contains:

Windows の場合:For Windows:

  • TelemetryMQTTWin32: Windows マシンでビルドされ実行されている Azure IoT ハブにテレメトリ メッセージを送信するためのコードが含まれています。TelemetryMQTTWin32: contains code to send a telemetry message to an Azure IoT hub, built and run on a Windows machine.

  • SubscribeMQTTWin32: Windows マシン上の特定の IoT ハブのイベントをサブスクライブするためのコードが含まれています。SubscribeMQTTWin32: contains code to subscribe to events of a given IoT hub on a Windows machine.

  • DeviceTwinMQTTWin32: Windows マシン上の Azure IoT ハブにあるデバイスのデバイス ツイン イベントに対してクエリを実行し、サブスクライブするためのコードが含まれています。DeviceTwinMQTTWin32: contains code to query and subscribe to the device twin events of a device in the Azure IoT hub on a Windows machine.

  • PnPMQTTWin32: IoT プラグ アンド プレイのプレビュー版のデバイス機能を使用して、Windows マシンでビルドされ実行されている Azure IoT ハブにテレメトリ メッセージを送信するためのコードが含まれています。PnPMQTTWin32: contains code to send a telemetry message with IoT Plug & Play preview Device capabilities to an Azure IoT hub, built and run on a Windows machine. IoT プラグ アンド プレイの詳細については、こちらを参照してください。More on IoT Plug & Play here

Linux の場合:For Linux:

  • MQTTLinux: Linux で実行されるコードとビルド スクリプトが含まれています (現時点までで WSL、Ubuntu、Raspbian でテスト済み)。MQTTLinux: contains code and build script to run on Linux (WSL, Ubuntu, and Raspbian have been tested so far).

  • LinuxConsoleVS2019: WSL (Windows Linux サブ システム) をターゲットとする VS2019 プロジェクトの同じコードが含まれています。LinuxConsoleVS2019: contains the same code but in a VS2019 project targeting WSL (Windows Linux sub system). このプロジェクトを使用すると、Linux で実行されているコードを Visual Studio からステップ バイ ステップでデバッグできます。This project allows you to debug the code running on Linux step by step from Visual Studio.

mosquitto_pub の場合:For mosquitto_pub:

このフォルダーには、Mosquitto.org によって提供される mosquitto_pub ユーティリティ ツールで使用される 2 つのサンプル コマンドが含まれています。This folder contains two samples commands used with mosquitto_pub utility tool provided by Mosquitto.org.

  • Mosquitto_sendmessage: デバイスとして機能する Azure IoT ハブに単純なテキスト メッセージを送信します。Mosquitto_sendmessage: to send a simple text message to an Azure IoT hub acting as a device.

  • Mosquitto_subscribe: Azure IoT ハブで発生しているイベントを表示します。Mosquitto_subscribe: to see events occurring in an Azure IoT hub.

MQTT プロトコルの直接使用 (モジュールとして)Using the MQTT protocol directly (as a module)

モジュール ID を使用して MQTT を介して IoT Hub に接続するのは、デバイス (で説明されています) と類似していますが、以下を使用する必要があります。Connecting to IoT Hub over MQTT using a module identity is similar to the device (described above) but you need to use the following:

  • クライアント ID を {device_id}/{module_id} に設定します。Set the client ID to {device_id}/{module_id}.

  • ユーザー名とパスワードを使用して認証する場合、ユーザー名を <hubname>.azure-devices.net/{device_id}/{module_id}/?api-version=2018-06-30 に設定し、パスワードとしてモジュール ID に関連付けられている SAS トークンを使用します。If authenticating with username and password, set the username to <hubname>.azure-devices.net/{device_id}/{module_id}/?api-version=2018-06-30 and use the SAS token associated with the module identity as your password.

  • 利用統計情報を公開するためのトピックとして devices/{device_id}/modules/{module_id}/messages/events/ を使用します。Use devices/{device_id}/modules/{module_id}/messages/events/ as topic for publishing telemetry.

  • WILL トピックとして devices/{device_id}/modules/{module_id}/messages/events/ を使用します。Use devices/{device_id}/modules/{module_id}/messages/events/ as WILL topic.

  • ツインの GET トピックと PATCH トピックは、モジュールとデバイスと同じです。The twin GET and PATCH topics are identical for modules and devices.

  • ツインの状態トピックは、モジュールとデバイスと同じです。The twin status topic is identical for modules and devices.

TLS または SSL の構成TLS/SSL configuration

MQTT プロトコルを直接使用するには、クライアントは TLS または SSL 経由で接続する "必要があります"。To use the MQTT protocol directly, your client must connect over TLS/SSL. この手順をスキップすると、接続エラーで失敗します。Attempts to skip this step fail with connection errors.

TLS 接続を確立するには、DigiCert Baltimore Root 証明書 をダウンロードして参照する必要がある場合があります。In order to establish a TLS connection, you may need to download and reference the DigiCert Baltimore Root Certificate. この証明書は、Azure が接続をセキュリティで保護するために使用するものの 1 つです。This certificate is the one that Azure uses to secure the connection. この証明書は、Azure-iot-sdk-c リポジトリ内で見つけることができます。You can find this certificate in the Azure-iot-sdk-c repository. これらの証明書について詳しくは、DigiCert の Web サイトをご覧ください。More information about these certificates can be found on Digicert's website.

Eclipse Foundation による Python バージョンの Paho MQTT ライブラリを使用してこれを実装する方法の例は、次のようになります。An example of how to implement this using the Python version of the Paho MQTT library by the Eclipse Foundation might look like the following.

最初に、コマンドライン環境から Paho ライブラリをインストールします。First, install the Paho library from your command-line environment:

pip install paho-mqtt

次に、Python スクリプトでクライアントを実装します。Then, implement the client in a Python script. プレースホルダーを次のように置き換えます。Replace the placeholders as follows:

  • <local path to digicert.cer> は、DigiCert Baltimore ルート証明書を含むローカル ファイルのパスです。<local path to digicert.cer> is the path to a local file that contains the DigiCert Baltimore Root certificate. このファイルは、証明書情報を Azure IoT SDK for C のcerts.c からコピーすることで作成できます。-----BEGIN CERTIFICATE----- 行と -----END CERTIFICATE----- 行を含め、すべての行の先頭と末尾の " 印を削除し、すべての行の末尾の \r\n 文字を削除します。You can create this file by copying the certificate information from certs.c in the Azure IoT SDK for C. Include the lines -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----, remove the " marks at the beginning and end of every line, and remove the \r\n characters at the end of every line.

  • <device id from device registry> は、IoT ハブに追加したデバイスの ID です。<device id from device registry> is the ID of a device you added to your IoT hub.

  • <generated SAS token> は、この記事で前述のように作成されたデバイスの SAS トークンです。<generated SAS token> is a SAS token for the device created as described previously in this article.

  • <iot hub name> は、IoT ハブの名前です。<iot hub name> the name of your IoT hub.

from paho.mqtt import client as mqtt
import ssl

path_to_root_cert = "<local path to digicert.cer file>"
device_id = "<device id from device registry>"
sas_token = "<generated SAS token>"
iot_hub_name = "<iot hub name>"


def on_connect(client, userdata, flags, rc):
    print("Device connected with result code: " + str(rc))


def on_disconnect(client, userdata, rc):
    print("Device disconnected with result code: " + str(rc))


def on_publish(client, userdata, mid):
    print("Device sent message")


client = mqtt.Client(client_id=device_id, protocol=mqtt.MQTTv311)

client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish

client.username_pw_set(username=iot_hub_name+".azure-devices.net/" +
                       device_id + "/?api-version=2018-06-30", password=sas_token)

client.tls_set(ca_certs=path_to_root_cert, certfile=None, keyfile=None,
               cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
client.tls_insecure_set(False)

client.connect(iot_hub_name+".azure-devices.net", port=8883)

client.publish("devices/" + device_id + "/messages/events/", "{id=123}", qos=1)
client.loop_forever()

デバイス証明書を使用して認証するには、上記のコード スニペットを次の変更で更新します (証明書ベースの認証を準備する方法については、「X.509 CA 証明書の入手方法」を参照してください)。To authenticate using a device certificate, update the code snippet above with the following changes (see How to get an X.509 CA certificate on how to prepare for certificate-based authentication):

# Create the client as before
# ...

# Set the username but not the password on your client
client.username_pw_set(username=iot_hub_name+".azure-devices.net/" +
                       device_id + "/?api-version=2018-06-30", password=None)

# Set the certificate and key paths on your client
cert_file = "<local path to your certificate file>"
key_file = "<local path to your device key file>"
client.tls_set(ca_certs=path_to_root_cert, certfile=cert_file, keyfile=key_file,
               cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)

# Connect as before
client.connect(iot_hub_name+".azure-devices.net", port=8883)

デバイスからクラウドへのメッセージの送信Sending device-to-cloud messages

接続に成功したら、デバイスから IoT Hub に devices/{device_id}/messages/events/ または devices/{device_id}/messages/events/{property_bag}トピック名として使用してメッセージを送信できます。After making a successful connection, a device can send messages to IoT Hub using devices/{device_id}/messages/events/ or devices/{device_id}/messages/events/{property_bag} as a Topic Name. {property_bag} 要素を使用すると、デバイスは追加のプロパティ付きのメッセージを URL エンコード形式で送信できるようになります。The {property_bag} element enables the device to send messages with additional properties in a url-encoded format. 次に例を示します。For example:

RFC 2396-encoded(<PropertyName1>)=RFC 2396-encoded(<PropertyValue1>)&RFC 2396-encoded(<PropertyName2>)=RFC 2396-encoded(<PropertyValue2>)…

注意

この {property_bag} 要素では、HTTPS プロトコルでのクエリ文字列と同じエンコードを使用します。This {property_bag} element uses the same encoding as query strings in the HTTPS protocol.

IoT Hub 実装固有のビヘイビアーのリストを以下に示します。The following is a list of IoT Hub implementation-specific behaviors:

  • IoT Hub では、QoS 2 メッセージはサポートされません。IoT Hub does not support QoS 2 messages. デバイス アプリから QoS 2 を使用したメッセージが発行されると、IoT Hub はネットワーク接続を閉じます。If a device app publishes a message with QoS 2, IoT Hub closes the network connection.

  • IoT Hub では、Retain メッセージは保持されません。IoT Hub does not persist Retain messages. デバイスが RETAIN フラグを 1 に設定してメッセージを送信すると、IoT Hub はそのメッセージに x-opt-retain アプリケーション プロパティを追加します。If a device sends a message with the RETAIN flag set to 1, IoT Hub adds the x-opt-retain application property to the message. この場合、IoT Hub は、Retain メッセージを保持するのではなく、バックエンド アプリにそのメッセージを渡します。In this case, instead of persisting the retain message, IoT Hub passes it to the backend app.

  • IoT Hub は、デバイスごとにアクティブな MQTT 接続を 1 つだけサポートします。IoT Hub only supports one active MQTT connection per device. 同じデバイス ID で新しい MQTT 接続が行われると、IoT Hub は既存の接続を破棄します。Any new MQTT connection on behalf of the same device ID causes IoT Hub to drop the existing connection.

詳しくは、メッセージング開発者のガイドをご覧ください。For more information, see Messaging developer's guide.

クラウドからデバイスへのメッセージの受信Receiving cloud-to-device messages

IoT Hub からメッセージを受信するには、デバイスで、devices/{device_id}/messages/devicebound/#トピック フィルターとして使用してサブスクライブする必要があります。To receive messages from IoT Hub, a device should subscribe using devices/{device_id}/messages/devicebound/# as a Topic Filter. トピック フィルター内の複数レベルのワイルドカード # は、デバイスがトピック名の追加プロパティを受信できるようにするためにのみ使用されます。The multi-level wildcard # in the Topic Filter is used only to allow the device to receive additional properties in the topic name. IoT Hub では、# または ? ワイルドカードを使用してサブトピックをフィルター処理することはできません。IoT Hub does not allow the usage of the # or ? wildcards for filtering of subtopics. IoT Hub はパブリッシャーとサブスクライバー間の汎用メッセージング ブローカーではないため、ドキュメント化されたトピック名とトピック フィルターのみをサポートします。Since IoT Hub is not a general-purpose pub-sub messaging broker, it only supports the documented topic names and topic filters.

デバイスは、devices/{device_id}/messages/devicebound/# トピック フィルターで表されるデバイス固有のエンドポイントへのサブスクライブが成功するまで、IoT Hub からメッセージを受信することはありません。The device does not receive any messages from IoT Hub, until it has successfully subscribed to its device-specific endpoint, represented by the devices/{device_id}/messages/devicebound/# topic filter. サブスクリプションが確立した後、デバイスは、サブスクリプション後に送信された cloud-to-device メッセージのみを受信します。After a subscription has been established, the device receives cloud-to-device messages that were sent to it after the time of the subscription. デバイスが CleanSession フラグを 0 に設定した状態で接続している場合、サブスクリプションは複数のセッションで保持されます。If the device connects with CleanSession flag set to 0, the subscription is persisted across different sessions. この場合、次回 CleanSession 0 の状態で接続したときに、デバイスは、切断中にデバイスに対して送信された未処理メッセージを受信します。In this case, the next time the device connects with CleanSession 0 it receives any outstanding messages sent to it while disconnected. ただし、デバイスが CleanSession フラグを 1 に設定して使用している場合は、デバイス エンドポイントにサブスクライブするまで、デバイスが IoT Hub からメッセージを受信することはありません。If the device uses CleanSession flag set to 1 though, it does not receive any messages from IoT Hub until it subscribes to its device-endpoint.

IoT Hub では、メッセージはトピック名 devices/{device_id}/messages/devicebound/ で配信されます。メッセージの プロパティがある場合は、devices/{device_id}/messages/devicebound/{property_bag} で配信されます。IoT Hub delivers messages with the Topic Name devices/{device_id}/messages/devicebound/, or devices/{device_id}/messages/devicebound/{property_bag} when there are message properties. {property_bag} には、メッセージ プロパティの URL でエンコードされた値/キーのペアが含まれています。{property_bag} contains url-encoded key/value pairs of message properties. プロパティ バッグに含められるのは、アプリケーション プロパティとユーザーが設定可能なシステム プロパティ (messageIdcorrelationId など) のみです。Only application properties and user-settable system properties (such as messageId or correlationId) are included in the property bag. システム プロパティの名前にはプレフィックス $ が付きます。アプリケーション プロパティでは、プレフィックスのない元々のプロパティ名が使用されます。System property names have the prefix $, application properties use the original property name with no prefix. プロパティ バッグの形式に関するその他の詳細については、「デバイスからクラウドへのメッセージの送信」を参照してください。For additional details about the format of the property bag, see Sending device-to-cloud messages.

クラウドからデバイスへのメッセージでは、プロパティ バッグの値は次の表に示されるように表記します。In cloud-to-device messages, values in the property bag are represented as in the following table:

プロパティ値Property value [表記]Representation 説明Description
null key プロパティ バッグにキーのみが含まれるOnly the key appears in the property bag
空の文字列empty string key= キーの後に等号が続き、値はないThe key followed by an equal sign with no value
null 以外の空でない値non-null, non-empty value key=value キーの後に等号と値が続くThe key followed by an equal sign and the value

以下の例では、次の 3 つのアプリケーション プロパティを含むプロパティ バッグを示します。値が nullprop1、空の文字列 ("") の prop2、"a string" という値の prop3The following example shows a property bag that contains three application properties: prop1 with a value of null; prop2, an empty string (""); and prop3 with a value of "a string".

/?prop1&prop2=&prop3=a%20string

デバイス アプリが QoS 2 を使用してトピックをサブスクライブしている場合、IoT Hub は SUBACK パケットに最大の QoS レベル 1 を許可します。When a device app subscribes to a topic with QoS 2, IoT Hub grants maximum QoS level 1 in the SUBACK packet. その後、IoT Hub は QoS 1 を使用してデバイスにメッセージを配信します。After that, IoT Hub delivers messages to the device using QoS 1.

デバイス ツインのプロパティの取得Retrieving a device twin's properties

まずデバイスが、操作の応答を受信するために、$iothub/twin/res/# にサブスクライブします。First, a device subscribes to $iothub/twin/res/#, to receive the operation's responses. 次に、デバイスは、空のメッセージをトピック $iothub/twin/GET/?$rid={request id} に送信します (要求 ID に値を指定します)。Then, it sends an empty message to topic $iothub/twin/GET/?$rid={request id}, with a populated value for request ID. その後サービスが、要求と同じ 要求 ID を使用して、トピック $iothub/twin/res/{status}/?$rid={request id} のデバイス ツイン データを含む応答メッセージを送信します。The service then sends a response message containing the device twin data on topic $iothub/twin/res/{status}/?$rid={request id}, using the same request ID as the request.

要求 ID には、IoT Hub メッセージング開発者のガイドに従って、メッセージ プロパティ値として有効な任意の値を指定できます。ステータスは、整数として検証されます。Request ID can be any valid value for a message property value, as per IoT Hub messaging developer's guide, and status is validated as an integer.

次の応答の例で示されているように、応答本文にはデバイス ツインのプロパティ セクションが含まれます。The response body contains the properties section of the device twin, as shown in the following response example:

{
    "desired": {
        "telemetrySendFrequency": "5m",
        "$version": 12
    },
    "reported": {
        "telemetrySendFrequency": "5m",
        "batteryLevel": 55,
        "$version": 123
    }
}

使用できる状態コードは次のとおりです。The possible status codes are:

StatusStatus 説明Description
200200 SuccessSuccess
429429 要求が多すぎます (スロットル)。IoT Hub スロットルに関するページを参照してください。Too many requests (throttled), as per IoT Hub throttling
5**5** サーバー エラーServer errors

詳しくは、デバイス ツイン開発者のガイドをご覧ください。For more information, see Device twins developer's guide.

デバイス ツインの報告されるプロパティの更新Update device twin's reported properties

報告されたプロパティを更新するために、デバイスでは、指定した MQTT トピック経由の公開を介して IoT Hub に要求が発行されます。To update reported properties, the device issues a request to IoT Hub via a publication over a designated MQTT topic. 要求を処理した後、IoT Hub は、別のトピックへの公開を介して、更新操作の成功または失敗の状態を応答します。After processing the request, IoT Hub responds the success or failure status of the update operation via a publication to another topic. デバイスでは、そのツイン更新要求の結果を通知するために、このトピックをサブスクライブできます。This topic can be subscribed by the device in order to notify it about the result of its twin update request. この種類の要求/応答のやり取りを MQTT 上で実装するために、その更新要求内でデバイスによって最初に提供される要求 ID ($rid) の概念を利用します。To implement this type of request/response interaction in MQTT, we leverage the notion of request ID ($rid) provided initially by the device in its update request. この要求 ID はIoT Hub からの応答にも含まれ、デバイスが以前の特定の要求に応答を関連付けることができるようにします。This request ID is also included in the response from IoT Hub to allow the device to correlate the response to its particular earlier request.

IoT Hub のデバイス ツインで報告されるプロパティをデバイスが更新する手順を次に示します。The following sequence describes how a device updates the reported properties in the device twin in IoT Hub:

  1. デバイスはまず、$iothub/twin/res/# トピックをサブスクライブして、IoT Hub から操作の応答を受信する必要があります。A device must first subscribe to the $iothub/twin/res/# topic to receive the operation's responses from IoT Hub.

  2. デバイスは、デバイス ツインの更新を含むメッセージを、$iothub/twin/PATCH/properties/reported/?$rid={request id} トピックに送信します。A device sends a message that contains the device twin update to the $iothub/twin/PATCH/properties/reported/?$rid={request id} topic. このメッセージには、要求 ID の値が含まれます。This message includes a request ID value.

  3. サービスは、トピック $iothub/twin/res/{status}/?$rid={request id} で報告されたプロパティ コレクションの新しい ETag 値を含む応答メッセージを送信します。The service then sends a response message that contains the new ETag value for the reported properties collection on topic $iothub/twin/res/{status}/?$rid={request id}. この応答メッセージでは、要求と同じ要求 ID が使われます。This response message uses the same request ID as the request.

要求メッセージの本文には、報告されるプロパティの新しい値を含む JSON ドキュメントが含まれています。The request message body contains a JSON document, that contains new values for reported properties. JSON ドキュメントの各メンバーは、デバイス ツインのドキュメントの対応するメンバーを更新または追加します。Each member in the JSON document updates or add the corresponding member in the device twin's document. メンバーを null に設定した場合、メンバーは包含オブジェクトから削除されます。A member set to null, deletes the member from the containing object. 次に例を示します。For example:

{
    "telemetrySendFrequency": "35m",
    "batteryLevel": 60
}

使用できる状態コードは次のとおりです。The possible status codes are:

StatusStatus 説明Description
204204 成功 (コンテンツは返されません)Success (no content is returned)
400400 正しくない要求。Bad Request. 無効な形式の JSONMalformed JSON
429429 要求が多すぎます (スロットル)。IoT Hub スロットルに関するページを参照してください。Too many requests (throttled), as per IoT Hub throttling
5**5** サーバー エラーServer errors

以下の python のコード スニペットは、(Paho MQTT クライアントを使用した) MQTT 経由でのツインの報告されたプロパティの更新プロセスを示しています。The python code snippet below, demonstrates the twin reported properties update process over MQTT (using Paho MQTT client):

from paho.mqtt import client as mqtt

# authenticate the client with IoT Hub (not shown here)

client.subscribe("$iothub/twin/res/#")
rid = "1"
twin_reported_property_patch = "{\"firmware_version\": \"v1.1\"}"
client.publish("$iothub/twin/PATCH/properties/reported/?$rid=" +
               rid, twin_reported_property_patch, qos=0)

上記のツインの報告されたプロパティの更新操作が成功すると、IoT Hub からの発行メッセージには次のトピックが含まれます: $iothub/twin/res/204/?$rid=1&$version=6。ここで、204 は成功を示す状態コードで、$rid=1 はコード内のデバイスによって提供された要求 ID に対応します。$version は、更新後のデバイス ツインの報告されたプロパティ セクションのバージョンに対応します。Upon success of twin reported properties update operation above, the publication message from IoT Hub will have the following topic: $iothub/twin/res/204/?$rid=1&$version=6, where 204 is the status code indicating success, $rid=1 corresponds to the request ID provided by the device in the code, and $version corresponds to the version of reported properties section of device twins after the update.

詳しくは、デバイス ツイン開発者のガイドをご覧ください。For more information, see Device twins developer's guide.

必要なプロパティの更新通知の受信Receiving desired properties update notifications

デバイスが接続されると、IoT Hub は、ソリューション バックエンドによって実行された更新の内容を含むトピック $iothub/twin/PATCH/properties/desired/?$version={new version} に通知を送信します。When a device is connected, IoT Hub sends notifications to the topic $iothub/twin/PATCH/properties/desired/?$version={new version}, which contain the content of the update performed by the solution back end. 次に例を示します。For example:

{
    "telemetrySendFrequency": "5m",
    "route": null,
    "$version": 8
}

プロパティの更新の場合、値 null は、JSON オブジェクト メンバーが削除されることを意味します。As for property updates, null values mean that the JSON object member is being deleted. また、$version がツインの望ましいプロパティ セクションの新しいバージョンを示していることに注意してください。Also, note that $version indicates the new version of the desired properties section of the twin.

重要

IoT Hub は、デバイスが接続されている場合にのみ変更通知を生成します。IoT Hub generates change notifications only when devices are connected. IoT Hub とデバイス アプリ間で目的のプロパティが同期された状態を保つには、デバイス再接続フローを必ず実装してください。Make sure to implement the device reconnection flow to keep the desired properties synchronized between IoT Hub and the device app.

詳しくは、デバイス ツイン開発者のガイドをご覧ください。For more information, see Device twins developer's guide.

ダイレクト メソッドへの応答Respond to a direct method

最初に、デバイスは $iothub/methods/POST/# にサブスクライブする必要があります。First, a device has to subscribe to $iothub/methods/POST/#. IoT Hub は、有効な JSON または空の本文と共にメソッド要求をトピック $iothub/methods/POST/{method name}/?$rid={request id} に送信します。IoT Hub sends method requests to the topic $iothub/methods/POST/{method name}/?$rid={request id}, with either a valid JSON or an empty body.

応答するために、デバイスは、有効な JSON を含むメッセージまたは 空の本文をトピック $iothub/methods/res/{status}/?$rid={request id} に送信します。To respond, the device sends a message with a valid JSON or empty body to the topic $iothub/methods/res/{status}/?$rid={request id}. このメッセージでは、要求 IDは、要求メッセージ内のものと一致する必要があり、ステータスは整数である必要があります。In this message, the request ID must match the one in the request message, and status must be an integer.

詳しくは、ダイレクト メソッド開発者のガイドをご覧ください。For more information, see Direct method developer's guide.

その他の注意点Additional considerations

最終的な考慮事項として、クラウド側で MQTT プロトコルの動作をカスタマイズする必要がある場合は、Azure IoT プロトコル ゲートウェイを確認する必要があります。As a final consideration, if you need to customize the MQTT protocol behavior on the cloud side, you should review the Azure IoT protocol gateway. このソフトウェアによって、IoT Hub と直接連携する高パフォーマンスのカスタム プロトコル ゲートウェイを展開できます。This software enables you to deploy a high-performance custom protocol gateway that interfaces directly with IoT Hub. Azure IoT プロトコル ゲートウェイでは、ブラウンフィールド MQTT デプロイメントまたは他のカスタム プロトコルに応じてデバイス プロトコルをカスタマイズすることができます。The Azure IoT protocol gateway enables you to customize the device protocol to accommodate brownfield MQTT deployments or other custom protocols. ただし、このアプローチでは、カスタム プロトコル ゲートウェイを実行して運用する必要があります。This approach does require, however, that you run and operate a custom protocol gateway.

次のステップNext steps

MQTT プロトコルについて詳しくは、MQTT のドキュメントをご覧ください。To learn more about the MQTT protocol, see the MQTT documentation.

IoT Hub のデプロイの計画に関する詳細については、以下をご覧ください。To learn more about planning your IoT Hub deployment, see:

IoT Hub の機能を詳しく調べるには、次のリンクを使用してください。To further explore the capabilities of IoT Hub, see: