動作報告
なかなか原因がわからなかったのですが、SASTokenを再設定すると動作しました。
それ以外は特に変更していません。
(2016/11/24)
注意
現在以下のサンプルは動作しません。
原因は不明ですが、接続はできるけどもデータの送受信ができていません。プログラム側ではエラーが発生しませんが、送受信とも反応がない状態です。
M2MQTTライブラリは更新されていないので、IoTHub側の問題(MQTTプロトコルゲートウェイ?)かと思います。
現在調査中ですが、解決にはもうしばらく時間がかかりそうです。
(2016/10/12 追記)
前回のサンプルプログラムはDeviceClientを使って作りました。
ただ、現在のDeviceClientではUWP上でMQTTプロトコルを選択できません。ついでにAMQPも選択できないのでWindows10IoTCoreではHTTPSでの接続しか選べない状況です。
Azure IoTHubはDeviceClientを使っての接続以外にMQTTクライアント(AMQPクライアントも)で直接接続することもできるのでUWPでも使えるM2MQTTライブラリを利用してみました。
準備
1.Azure IoTHubを作成(初めての人はこちらを参照)
2.VisualStudio2015
3.Windows10搭載PC(Windows10IoTCore上で試すならWindows8.1でも可)
4.VisualStudioで空のアプリ(ユニバーサルWindows)を選んでプロジェクトを作成します。
5.DeviceExplorerのインストール(まだの人はこちらを参照)
プログラム
画面用
<Page
x:Class="IoTHub_MQTT_UWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:IoTHub_MQTT_UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBox x:Name="tBox1" HorizontalAlignment="Left" Margin="10,43,0,0" TextWrapping="Wrap" Text="Hello IoTHub" VerticalAlignment="Top" Width="780"/>
<Button x:Name="btn_send" Content="Send Message" HorizontalAlignment="Left" Margin="10,90,0,0" VerticalAlignment="Top" Click="btn_send_Click"/>
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="10,160,0,0" TextWrapping="Wrap" Text="Racieved Message" VerticalAlignment="Top"/>
<TextBlock x:Name="tBlock1" HorizontalAlignment="Left" Margin="10,185,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="780" FontSize="21.333"/>
</Grid>
</Page>
プログラム本体
using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using System.Diagnostics;
using System.Text;
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;
// 空白ページのアイテム テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 を参照してください
namespace IoTHub_MQTT_UWP
{
/// <summary>
/// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。
/// </summary>
public sealed partial class MainPage : Page
{
//クライアント
private static MqttClient Client;
//IoTHub名(URL)
private const string IoTHubName = "[IoTHub Address]";
//デバイスID
private const string DeviceId = "[DeviceId]";
//MQTTブローカーアドレス
private string UserName = string.Format("{0}/{1}", IoTHubName, DeviceId);
//アクセストークン
private const string SASToken = "[SAS Token]";
private static string TopicDevice2Service;
private static string TopicService2Device;
private const int MqttPort = 8883;
/// <summary>
///
/// </summary>
public MainPage()
{
this.InitializeComponent();
Loaded += MainPage_Loaded;
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
try
{
Client = new MqttClient(IoTHubName, MqttPort, true, MqttSslProtocols.TLSv1_0);
//接続
Client.Connect(DeviceId, UserName, SASToken);
}
catch (Exception ex)
{
Debug.WriteLine("Error in sample: {0}", ex.Message);
}
//受信イベントの登録
Client.MqttMsgPublishReceived += this.onReceive;
//MQTT Topic
TopicService2Device = string.Format("devices/{0}/messages/devicebound/#", DeviceId);
//受信するトピックの登録
Client.Subscribe(new[] { TopicService2Device }, new[] { MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE });
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void onReceive(object sender,MqttMsgPublishEventArgs e)
{
//受信イベントからメッセージの取り出し
string msg = Encoding.UTF8.GetString(e.Message);
//メッセージをUIスレッドに表示
var task = this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
tBlock1.Text = msg;
});
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_send_Click(object sender, RoutedEventArgs e)
{
//メッセージの送信先
TopicDevice2Service = string.Format("devices/{0}/messages/events", DeviceId);
string Data;
Data = tBox1.Text;
//メッセージの送信(Publish)
Client.Publish(TopicDevice2Service, Encoding.UTF8.GetBytes(Data));
}
}
}
・あらかじめNugetパッケージマネージャーから「M2MQTT」をインストールしておきます。
・22行目の[IoTHub Address]を「IoTHub名.azure-devices.net」に置き換えます。
・24行目の[DeviceId]を自分がつけたDeviceIdに置き換えます。
・DeviceExplorerを立ち上げて、「Generate SAS」ボタンをクリックすると下にSAS Tokenが表示されます。表示された内容をコピーして29行目の[SAS Token]と置き換えます。
実行
DeviceExplorerを立ち上げたまま、プログラムを実行します。
送信の確認
DeviceExplorerをDataタブに切り替えて「Monitor」ボタンをクリックします。
プログラムのテキストボックスに好きな文字を入力して、「Send Message」ボタンをクリックすると、DeviceExplorerのEvent Hub Dataに送信した文字が表示されます。(それ以外にもPropertie等も表示されます。これは設定で含まないようにできるんでしょうか? Dataは問題なく送れているのでそのままにしています。)
受信の確認
DeviceExplorerをMessage To Deviceタブを選択します。
Message:に送信したい文字を入力します。(日本語は不可。DeviceExplorerが未対応)
「Send」ボタンをクリックすると少し間が空いてからOutputにDeviceに送信した内容が表示されます。プログラムのRecieved Messageの下に送信した文字が表示されたら受信に成功しています。
最後に
今回はDeviceClientを利用せずにAzure IoTHubに接続してみました。
ArduinoなどでもMQTTクライアントが利用できる環境であれば、Azure IoTHubに接続できると思います。
機会があれば、サンプルプログラムを書いてみたいと思います。