Xamarin.FormsからAzure Event Hubsに大量のメッセージを送信する

これは、Xamarin その1 Advent Calendar 2017の7日目のエントリーです。

先日、Tech Summit 2017というイベントでAzure Cosmos DB を使った高速分散アプリケーションの設計パターンというセッションを担当させていただいたのですが、その中で取り上げた設計パターンのひとつとして「リアルタイムデータ分析」がありました。

この設計パターンでは、イベント発行元にIoT機器を想定していたのですが、良く考えたらXamarinで作成したアプリにも適用できそうだなと思い今回検証してみました。

リアルタイムデータ分析パターン

活用シナリオとしては、操作ログの送信やアプリの状態保存など、アプリで何らかのイベントが発生したタイミングで、イベントデータをクラウドにとりあえず送信しておきたいような場面です。アプリケーションログなどの定型イベントは、App Centerのような仕組みを使えば勝手にイベントが飛ぶはずなので、ここではカスタムなイベントデータを送信、蓄積したい時のシナリオを想定しています。

Azure Event Hubsを利用する

このような処理では、クラウド側には送信側のデバイスから大量にイベントが送信されても耐えられるような設計が必要です。バックエンドにAzureを使うなら、Event Hubsを使うのがおすすめです。Event Hubsはざっくりいうと、不特定の比較的大量なメッセージを受け止めて、後続の連携するサービスにデータを渡してくれるサービスです。Stream Analyticsなど簡単に連動できるサービスが多いので、クラウド側のイベントデータの入口としてよく使われています。

まず、Azure Portal を使用して Event Hubs 名前空間とイベント ハブを作成するあたりを参考にしてAzure上にEvent Hubsをプロビジョニングしておきましょう。残念ながら無償プランはありませんが、Basicプランならそれほど課金されません。料金の詳細はEvent Hubs の価格を確認して下さい。

Xamarin.FormsでEvent Hubs SDKを使う

Event Hubsへのメッセージ送信元となるクライアント側は、REST APIやSDKを使うことでEvent Hubsと通信することができます。SDKは、 .NET Framework用と .NET Standard用がありますが、Xamarin.Formsでは後者を選択する必要があります。ライブラリのGithubリポジトリは.NET Standard client library for Azure Event Hubsです。

実は、世の中にこのパターンのサンプルコードがほとんどなく、今回の検証にはかなり苦労しましたが、最終的にはなんとか .NET StandardのXamarin.FormsからでもSDKが使えることがわかりました。デバッグを手伝ってくれたJXUGメンバーの@masatoruさんには大変感謝しています!

.NET Standard対応のXamarin.Formsプロジェクトを作成

当初このセクションでは、従来のPCLから .NET Standardへの書きかえ方法を書いていたのですが、途中でVisual Studioの15.5が降ってきて、普通に .NET StandardでFormsのプロジェクトを作成できるようになってしまい、めでたくこのセクションに書いていたTIPSは全てお蔵入りとなりました。。。

Visual Studio 2017(15.5)によるプロジェクト作成

まず、上記のような設定で空のXamarin.Formsプロジェクトを作成します。Code Sharing Strategyで「.NET Standard」を選択できるようになったのは嬉しいですね!

プロジェクトが出来たら、FormsのプロジェクトでNugetパッケージMicrosoft.Azure.Eventhubsを検索し追加します。

イベント送信処理の実装

Event Hubsへのイベント送信処理実装はそれほど難しくありません。基本的にはEvent Hubクライアントを作成し、SendAsync()にメッセージを渡して送信するだけです。

送信処理はEventSenderというクラスに集約するように実装したので、あとはメッセージを送信したいイベントハンドラから送信メソッドを呼べばOKです。なお、本格的に実装する場合は、Event Hubs の認証とセキュリティ モデルの概要あたりを参考にしてSASトークンを使った認証をするように実装しましょう。

このように、わりと簡単にEvent Hubsへのメッセージ送信処理を実装できるのですが、私が調べた限りではXamarin + Event Hubsのサンプルコードは世の中にほとんど存在していません。もしかすると、.NET Standard化してはじめて普通に使えるようになったのかもしれません。

いずれにせよ、今後はXamarinからAzure Event Hubsを簡単に利用できることがわかりましたので、大量のメッセージをクラウドに送りつけておきたいような場面に遭遇した際には、このエントリーを思い出していただければ幸いです。

ちなみに一度Azure Event Hubsにメッセージを送っておけば、その先はStream Analyticsでリアルタイムにデータを処理することも、Azure FunctionsのEvent Hubsトリガーに引っ掛けて後続処理を行うことも、その両方をつなぐこともできます。Xamarinのアプリ内で発生したイベントを起点にクラウド上でいろいろな処理を実行するパイプラインを設計することが可能になりますよ!