メソッドMicrosoft.Azure.Devices.Client.DeviceClient.UploadToBlobAsyncは、基本的に、Azure IoT Hub経由でBLOBアップロードセッションのREST API呼び出しをラッパーします。このセッションのシーケンスは、 ステップ1のような3つのステップに分かれています。 Azure IoT Hub(公開セッション)からアップロード情報のリファレンスを入手してください ステップ2。受信した参照情報に基づいてブロブをアップロードする ステップ3。アップロードプロセスの結果を投稿するセッションを閉じます。
次のコードスニペットは、PCLプロジェクトで実現上記の手順の一例を示す:許可ヘッダの
private async Task UploadToBlobAsync(string blobName, Stream source, string iothubnamespace, string deviceId, string deviceKey)
{
using(HttpClient client = new HttpClient())
{
// create authorization header
string deviceSasToken = GetSASToken($"{iothubnamespace}.azure-devices.net/devices/{deviceId}", deviceKey, null, 1);
client.DefaultRequestHeaders.Add("Authorization", deviceSasToken);
// step 1. get the upload info
var payload = JsonConvert.SerializeObject(new { blobName = blobName });
var response = await client.PostAsync($"https://{iothubnamespace}.azure-devices.net/devices/{deviceId}/files?api-version=2016-11-14", new StringContent(payload, Encoding.UTF8, "application/json"));
var infoType = new { correlationId = "", hostName = "", containerName = "", blobName = "", sasToken = "" };
var uploadInfo = JsonConvert.DeserializeAnonymousType(await response.Content.ReadAsStringAsync(), infoType);
// step 2. upload blob
var uploadUri = $"https://{uploadInfo.hostName}/{uploadInfo.containerName}/{uploadInfo.blobName}{uploadInfo.sasToken}";
client.DefaultRequestHeaders.Add("x-ms-blob-type", "blockblob");
client.DefaultRequestHeaders.Remove("Authorization");
response = await client.PutAsync(uploadUri, new StreamContent(source));
// step 3. send completed
bool isUploaded = response.StatusCode == System.Net.HttpStatusCode.Created;
client.DefaultRequestHeaders.Add("Authorization", deviceSasToken);
payload = JsonConvert.SerializeObject(new { correlationId = uploadInfo.correlationId, statusCode = isUploaded ? 0 : -1, statusDescription = response.ReasonPhrase, isSuccess = isUploaded });
response = await client.PostAsync($"https://{iothubnamespace}.azure-devices.net/devices/{deviceId}/files/notifications?api-version=2016-11-14", new StringContent(payload, Encoding.UTF8, "application/json"));
}
}
我々はsasTokenを必要とするので、次のコードは、その実装を示しています。
private string GetSASToken(string resourceUri, string key, string keyName = null, uint hours = 24)
{
var expiry = Convert.ToString((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds + 3600 * hours);
string stringToSign = System.Net.WebUtility.UrlEncode(resourceUri) + "\n" + expiry;
HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(key));
var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
var sasToken = keyName == null ?
String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}", System.Net.WebUtility.UrlEncode(resourceUri), System.Net.WebUtility.UrlEncode(signature), expiry) :
String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}", System.Net.WebUtility.UrlEncode(resourceUri), System.Net.WebUtility.UrlEncode(signature), expiry, keyName);
return sasToken;
}
上記の実装では、手順2の再試行メカニズムは処理されません。