Azure IoTHubがリリースされた当初は対応しているプロトコルはHTTPS、AMQPでした。しばらくしてAzure IoT プロトコル ゲートウェイがリリースになってMQTTプロトコルも使えるようにはなったのですが、その時はゲートウェイを自分で用意する必要がありました。
今年2月になってIoTHubが直接MQTTプロトコルでの接続をサポートするようになりました。
今回はMQTTプロトコルでIoTHubに接続するサンプルプログラムを紹介します。
参考にしたのはAzure-IoT-SDKのMQTTサンプルプログラムです。(プログラム自体はほぼ一緒です。送るメッセージを変更しています。)
準備
- Azure IoTHubを作成。作成方法はこちら
- VisualStudio2015で[新規作成]-[プロジェクト]-[Visual C#]-[Windows]-[コンソールアプリケーション]を選択してプロジェクトを作成。
- ソリューションエクスプローラーの[参照]を右クリックして[Nugetパッケージの管理]を選択して、Nugetパッケージマネージャーで「devices client」と検索してください。リストに「Microsoft.Azure.Devices.Client」が表示されたらインストールします。
プログラム
using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.Devices.Client;
namespace MQTT_TEST
{
class Program
{
//IoTHubに接続するためのコネクション文字列
private const string deviceCn = "[replace]";
//メッセージ送信数
private static int MESSAGE_COUNT = 5;
/// <summary>
///
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
try
{
//デバイスクライアントのインスタンス(プロトコルをMQTTに指定)
DeviceClient client = DeviceClient.CreateFromConnectionString(deviceCn, TransportType.Mqtt);
//セッションを開く
client.OpenAsync().Wait();
//IoTHubへメッセージの送信
SendEvent(client).Wait();
//IoTHubからメッセージを受信
ReceiveCommands(client).Wait();
}
catch (AggregateException ex)
{
foreach (Exception exception in ex.InnerExceptions)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", exception);
}
}
catch(Exception ex)
{
Console.WriteLine();
Console.WriteLine("Error in sample: {0}", ex.Message);
}
Console.WriteLine("Press enter to exit...");
Console.ReadLine();
}
/// <summary>
///
/// </summary>
/// <param name="client"></param>
/// <returns></returns>
static async Task SendEvent(DeviceClient client)
{
//送信メッセージ用
string dataBuffer;
//コンソール出力
Console.WriteLine("Device sending {0} messages to IoTHub...\n", MESSAGE_COUNT);
for (int count=0; count < MESSAGE_COUNT; count++)
{
//メッセージ作成
dataBuffer = "メッセージ:" + count.ToString();
//作成したメッセージをバイトデータに変換して、Messageオブジェクトに代入
Message eventMessage = new Message(Encoding.UTF8.GetBytes(dataBuffer));
//コンソール出力
Console.WriteLine("\t{0} Sending message: {1}, Data: [{2}]", DateTime.Now.ToLocalTime(), count, dataBuffer);
//非同期でメッセージを送信
await client.SendEventAsync(eventMessage);
}
}
/// <summary>
///
/// </summary>
/// <param name="client"></param>
/// <returns></returns>
static async Task ReceiveCommands(DeviceClient client)
{
//コンソールに出力
Console.WriteLine("\nDevice waiting for commands from IoTHub...\n");
Message recievedMessage;
string messageData;
//メッセージを受信するためのループ
while (true)
{
//一秒ごとにメッセージの受信を確認
recievedMessage = await client.ReceiveAsync(TimeSpan.FromSeconds(1));
if (recievedMessage != null)
{
//届いたメッセージを文字列に変換
messageData = Encoding.ASCII.GetString(recievedMessage.GetBytes());
//コンソール出力
Console.WriteLine("\t{0}> Received message: {1}", DateTime.Now.ToLocalTime(), messageData);
//受信完了を待つ
await client.CompleteAsync(recievedMessage);
}
}
}
}
}
11行目の[replace]の箇所はDevice Explorerで登録したデバイスのConnectionStringと置き換えます。
Device Explorerのモニターを有効にしてプログラムを実行すると送信したメッセージが表示されます。
また、Device Explorerの「Message To Device」タブからメッセージを送信するとプログラムコンソールにIoTHubからのメッセージが表示されます。
まとめ
DeviceClientを利用できる環境ではHTTPSやAMQPと同様の方法でデータの送受信が可能になっています。
詳しくはわからないのですが、IoTHub側にプロトコルゲートウェイを用意してあるのではないかと思います。
また、DeviceClientを利用できない環境では、決められたIoTHubのエンドポイントにアクセスることでメッセージの送受信ができるようです。
機会があればDeviceClientを使わないサンプルも作ってみたいと思います。