Azure IoT Hubに、HTTP REST APIでメッセージを送る方法です。
Azure IoT Device Client SDKは使いません。
HTTP RESTでメッセージを送信するまでの流れは、こんな感じになります。
- デバイスの登録 (Azureポータルで作業)
- SASトークンの作成 (C#)
- RESTでメッセージを送信 (C#)
- スポンサーリンク
やってみる
デバイスの登録
Azureポータルで、メッセージを送信するデバイスを登録します。
Iot Hubのページから、[IoT devices] -> [Add]を選択
下の画面で、Iotデバイスを登録します。
Device IDは任意の値、認証には Symmetric keyを選択します。
一覧から登録したデバイスを選択して、デバイスの詳細を表示します。
ここに表示される、[Device ID][Primary Key(共有アクセスキー)]を、後から使うのでメモしておきます。
SASトークンの作成 (C#)
ここからC#のコードを組んでいきます。
デバイスIDと共有アクセスキーから、SASトークンを生成するメソッドを作ります。
ここで作成するGenerateSasToken()
メソッドを、後述するメッセージ送信のサンプルコードから呼びます。
using System;
using System.Globalization;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
/// <summary>
/// Azure IOT Hub用のSASトークンの作成
/// </summary>
/// <returns>SASトークン</returns>
/// <param name="resourceUri">リソースURL</param>
/// <param name="key">共有アクセスキー</param>
/// <param name="policyName">ポリシー名(今回使用しない)</param>
/// <param name="expiryInSeconds">有効期限(秒)</param>
public static string GenerateSasToken(string resourceUri, string key, string policyName, int expiryInSeconds = 3600) {
TimeSpan fromEpochStart = DateTime.UtcNow - new DateTime(1970, 1, 1);
string expiry = Convert.ToString((int)fromEpochStart.TotalSeconds + expiryInSeconds);
string stringToSign = WebUtility.UrlEncode(resourceUri) + "\n" + expiry;
HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(key));
string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
string token = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}", WebUtility.UrlEncode(resourceUri), WebUtility.UrlEncode(signature), expiry);
if (!String.IsNullOrEmpty(policyName)) {
token += "&skn=" + policyName;
}
return token;
}
RESTでメッセージを送信 (C#)
.NET Framework標準の HttpClient
クラスを使って、RESTでメッセージを送信します。
今回は、JSONのデータを送ります。
//(1)環境設定
private const string IOT_HUB_NAME = "<iothubname>.azure-devices.net";
private const string SIGNING_KEY = "<共有アクセスキー>";
private const string DEVICE_ID = "<デバイスID>";
public static void Send() {
//(2)SASトークンを作成する
var resourceUri = $"{IOT_HUB_NAME}/devices/{DEVICE_ID}";
var sasToken = GenerateSasToken(resourceUri, SIGNING_KEY, null);
//(3)URLの組み立て
var url = $"https://{IOT_HUB_NAME}/devices/{DEVICE_ID}/messages/events?api-version=2018-06-30";
HttpResponseMessage res = null;
//HTTP RESTでメッセージを送信する
using (var client = new HttpClient()) {
var request = new HttpRequestMessage(HttpMethod.Post, url);
//(4)HTTPヘッダに、SASトークンを設定
request.Headers.Add("Authorization", sasToken);
var json = @"{""msg"":""Test Message""}";
var content = new StringContent(json, Encoding.UTF8, @"application/json");
request.Content = content;
res = client.SendAsync(request).Result;
//メッセージが正常に送信されると、IoT Hubからは、204が返ってくる
if (res.StatusCode == HttpStatusCode.NoContent) {
Console.WriteLine("送信しました。");
}
}
}
ポイントは以下の通り。
(1)Iot Hub名、デバイスの共有アクセスキーおよび、デバイスIDを指定します。
Iot Hub名は、Azure Iot Hubのトップページから確認できます。
デバイスID、共有アクセスキーは、デバイスの詳細ページから確認できます。
(2)上で作成したメソッドを使って、SASトークンを作成します。
(3)送信先URLには、デバイスIDを含めます。
(4)HTTPヘッダに、作成したSASトークンを指定します。
メッセージにプロパティを設定するには
REST APIで、メッセージにプロパティ (application property) を指定する場合は、リクエストヘッダに設定します。
ヘッダに設定するプロパティ名には、iothub-app-
の接頭辞を付けて設定します。
<サンプルコード>
// "myprop"というプロパティを IotHubに送信する場合
request.Headers.Add("iothub-app-myprop", value);
(おまけ) RESTでメッセージを受信(C#)
IoT Hubからメッセージ通知し、REST APIで受信する例です。
送信の例と同じように、SASトークンを発行してから、APIを叩きます。
メッセージを受信した後に、Iot Hubに完了通知を送って、メッセージを削除します。
public static void Revive() {
//SASトークンを作成する
var resourceUri = $"{IOT_HUB_NAME}/devices/{DEVICE_ID}";
var sasToken = GenerateSasToken(resourceUri, SIGNING_KEY, null);
//URLの組み立て
var url = $"https://{IOT_HUB_NAME}/devices/{DEVICE_ID}/messages/deviceBound?api-version=2018-06-30";
HttpResponseMessage res = null;
using (var client = new HttpClient()) {
var request = new HttpRequestMessage(HttpMethod.Get, url);
//HTTPヘッダに、SASトークンを設定
request.Headers.Add("Authorization", sasToken);
res = client.SendAsync(request).Result;
if (res.StatusCode == HttpStatusCode.OK) {
Console.WriteLine(res.Content.ReadAsStringAsync().Result);
} else {
//通知がない場合
Console.WriteLine("No Message!");
}
//受信したメッセージの完了通知をIoT Hubに送信します。
//これにより、Iot Hubよりメッセージが削除される模様
var etag = res.Headers.ETag?.Tag.Replace("\"", string.Empty);
if (etag != null) {
var restUriComplete = $"https://{IOT_HUB_NAME}/devices/{DEVICE_ID}/messages/deviceBound/{etag}?api-version=2018-06-30";
var deleteRequest = new HttpRequestMessage(HttpMethod.Delete, restUriComplete);
deleteRequest.Headers.Add("Authorization", sasToken);
var resDelete = client.SendAsync(deleteRequest).Result;
}
}
}
上のコードを試す為に、Azureポータルからメッセージを送信してみます。
Iot Hubのデバイス詳細ページから[Message to device]を選択して、メッセージを送信します。
実行すると、コンソールにAzureポータルから送信したメッセージが表示されると思います。
おわりに
<関連記事>
■ C# (.net) で使える MQTT クライアント (Paho M2Mqtt)
C#で 、MQTTメッセージを送受信するライブラリの、「M2Mqtt」の使い方について、解説しています。
無料のBrokerサーバを使って、簡単にお試しする事が出来ます。
スポンサーリンク
参考
共有アクセスキーの、プライマリ・セカンダリについて
共有アクセスキーには、プライマリとセカンダリの2つがあり、セキュリティの観点からアクセスキーを一定期間でローテーションすることを目的としています。
運用として、アクセスに使うキーをプライマリからセカンダリに変更し、その間にプライマリのキーを再生成してから元に戻す運用を行います。
共有アクセスキーのローテイションは、Azureポータルから行います。
デバイス詳細画面の [Regenerate keys]をクリックして、共有アクセスキーの再生成を行います。
Azure IoT Hubを生MQTTS(mosquitto)やHTTP RESTで使う方法
https://qiita.com/ma2shita/items/032370350cba282d35ff
Azure IoT Hubを使ってみた
https://qiita.com/linyixian/items/e319c5f63f9e57459ac0
IoT Hub へのアクセスの制御
Azure IoT Device Client SDK
今回は使っていませんが、Azure IoT Device Client SDK
は、nuget からインストールできます。
0 件のコメント:
コメントを投稿