前回の反対にIoT Hubからメッセージを受信する方法です。ドキュメントにもあるのですが、IoT Hubではメッセージを最低1回は受信するように保証(到達保証)する ことができますが、そのためにはデバイス側で受け取ったという通知をIoTHubに返してあげる必要があります。
というわけでコードです。前回のコードに追加して、Grid
がロードされた時からメッセージの受信を待機して、受信したらテキストボックスに表示してまた待機するという繰り返しです。
private void Grid_Loaded(object sender, RoutedEventArgs e) { ReceiveDataFromAzure() .ContinueWith(t => Debug.WriteLine(t.Exception), TaskContinuationOptions.OnlyOnFaulted); } public async Task ReceiveDataFromAzure() { var deviceClient = DeviceClient.CreateFromConnectionString("<ConnectionString>", TransportType.Http1); while (true) { var receivedMessage = await deviceClient.ReceiveAsync(); if (receivedMessage != null) { var messageData = Encoding.UTF8.GetString(receivedMessage.GetBytes()); textBox1.Text = messageData; await deviceClient.CompleteAsync(receivedMessage); } } }
なお、インストーラーで配布されているDeviceExploreだとマルチバイト文字が正しく送信できません。理由はDevice Explorerで入力した文字列に対してASCIIでバイト配列を取得しているためです... 日本語を送信したい場合は、ソースコードを持ってきてこの部分をUTF8にしてビルドすればOKです。IoT Hub側のやりとりはbyte配列なので特に制約があるわけではないと思うのですが。
azure-iot-sdks/MainForm.cs at 2015-11-30 · Azure/azure-iot-sdks · GitHub
さて、DeviceClientを生成するときの第2引数にHttp1というのを渡しています。その名のとおり、HTTP/1 をプロトコルに選択しているのですが、送信以上にサーバープッシュができないためポーリングせざるをえない受信で負荷がかかるとドキュメントにあります。本番環境では25分に1回未満とあるのでなかなかつらいところでしょう。
じゃあ、そのドキュメントにあるAMQPにすればいいのでは?となるのですが、残念ながらUWPでは未実装でNotImplementedException
が飛んできます。
azure-iot-sdks/DeviceClient.cs at 2015-11-30 · Azure/azure-iot-sdks · GitHub
UWPでAMQPで送信するライブラリもあるみたいですが、Backlogにも載っているようです。
動きがあれば試してみようと思います。