サンプルアプリケーションの作成
それでは実際に、キューを使用して、WebロールとWorkロールを連携させるサンプルを作成してみましょう。
サンプルの概要
次の図2のような、シンプルな画像共有アプリケーションを作成してみます。
このサンプルは、画像ファイルのアップロード、サムネイル画像の作成、サムネイル画像の一覧表示の機能を持っています。サムネイル画像は、アップロード時の指定により、そのままの向き、90度回転、180度回転のいずれかの状態で作成されます。
システム構成についても説明します。次の図3が示すように、WebロールとWorkerロールを各々1つずつ、そしてブロブとキューの2種類のWindows Azureストレージを使用します。
Webロールでは、オリジナルの画像ファイルをブロブにアップロードし、サムネイル作成を指示するメッセージをキューに追加します。また、Workerロールで作成された、最新のサムネイル画像をブロブから取得し、一覧表示を行います。
一方、バックグラウンド上で起動しているWorkerロールでは、キューにメッセージがあるかどうかを監視しています。キューにメッセージがあるなら、すぐにメッセージを取得し、メッセージの内容に基づいてサムネイル画像を作成し、ブロブにアップロードします。
このように、すぐに応答できるリクエストはWebロールで処理し、処理に時間のかかるプロセス(サンプルでは、サムネイル画像の作成)についてはWorkerロールで処理し、両ロール間の連携のためにキューを使用する方法を理解することができるでしょう。
サンプルの作成
それでは早速、サンプルを作成してみましょう。以下の手順で作成します。
(1)管理者権限で、Visual Studioを起動する
Development FabricやDevelopment Storageなどの開発環境を起動する際には管理者権限を必要とするので、Visual Studioを管理者として起動します。Windowsの[スタート]メニューからVisual Studioのアイコンを見つけ右クリックし、[管理者として実行]を選択します。
(2)新しいプロジェクトを作成する
新規にプロジェクトを作成します。「新しいプロジェクト」ダイアログ中で、プロジェクトの種類は「Visual C#」、テンプレートは「Windows Azure Cloud Service」を選択します。プロジェクト名は任意ですが、ここでは「AzureStorageQueueSample」としておきます。
(3)ソリューションに、WebロールとWorkerロールを各々1つずつ追加する
新しいプロジェクトを作成すると、次に「New Cloud Service Project」ダイアログが表示されます。次の図4にあるように、左側の[Roles]リストから、「Visual C#」内の「ASP.NET Web Role」(Webロール)を選択し[>]ボタンをクリックして、右側の[Cloud Service Solution]リストに追加します。同様に、左側の[Roles]リストから、「Visual C#」内の「Worker Role」(Workerロール)を選択し、右側の[Cloud Service Solution]リストに追加します。最後に、[OK]ボタンをクリックします。
すると、次の図5にあるように、ソリューション配下に3つのプロジェクトが作成されます。「AzureStorageQueueSample」がクラウドサービスプロジェクトを、「WebRole1」がWebロール用プロジェクト、「WorkerRole1」がWorkerロール用プロジェクトを表しています。デフォルトで、「WebRole1」プロジェクトにはDefault.aspxが、「WorkerRole1」プロジェクトにはWorkerRole.csが作成されます。
(4)Webロールの接続文字列を追加する
Windows Azureストレージへのアクセスのための接続文字列を追加します。
ソリューションエクスプローラから、「AzureStorageQueueSample」クラウドサービスプロジェクト内の「Roles」フォルダにある「WebRole1」を右クリックし、[プロパティ]を選択します。表示されたプロパティ画面中の左側にある[Settings]タブをクリックします。[Add Setting]ボタンをクリックし、次の図6のように、Windows Azureストレージへのアクセスのための接続文字列を追加します。Nameは任意ですが、ここでは「DataConnectionString」と入力し、Typeには「ConnectionString」を選択します。Valueには「UseDevelopmentStorage=true」と入力します。これにより、Windows Azureストレージのローカル仮想ストレージ環境であるDevelopment Storageの使用を指定します。
(5)Workerロールも接続文字列を追加する
(4)と同様の方法で、WorkerロールにもWindows Azureストレージへのアクセスのための接続文字列を追加します。
ソリューションエクスプローラから、「AzureStorageQueueSample」クラウドサービスプロジェクト内の「Roles」フォルダにある「WorkerRole1」を右クリックし、[プロパティ]を選択します。表示されたプロパティ画面中の左側にある[Settings]タブをクリックします。[Add Setting]ボタンをクリックし、Windows Azureストレージへのアクセスのための接続文字列を追加します。Nameには「DataConnectionString」と入力し、Typeには「ConnectionString」を選択します。Valueには「UseDevelopmentStorage=true」と入力します。
上記の(4)と(5)の手順で接続文字列を追加した後、ソリューションエクスプローラから、「AzureStorageQueueSample」クラウドサービスプロジェクト内のサービス定義ファイル(ServiceDefinition.csdef)やサービス構成ファイル(ServiceConfiguration.cscfg)を開いてみてください。WebロールとWorkerロールに追加した接続文字列の定義と設定値が反映されていることが分かるはずです。
(6)Default.aspxにコントロールを配置する
次の図7のように、「WebRole1」プロジェクト内のDefault.aspxの[デザイン]ビューにコントロールを配置します。
上から順に、FileUploadコントロール、RadioButtonListコントロール、アップロード用のButtonコントロール、サムネイル表示用のButtonコントロール、サムネイル画像表示用にDataListコントロールを貼り付けます。
最終的には、Default.aspxの[ソース]ビューで表示すると、次のリスト1のようになります。
…前略… <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Windows Azureストレージサンプル</title> </head> <body> <form id="form1" runat="server"> <div> 画像ファイル: <asp:FileUpload ID="FileUpload1" runat="server" /> <br /> <asp:RadioButtonList ID="RadioButtonList1" runat="server" RepeatDirection="Horizontal"> *1 <asp:ListItem Selected="True" Value="0">そのまま</asp:ListItem> <asp:ListItem Value="1">90度回転</asp:ListItem> <asp:ListItem Value="2">180度回転</asp:ListItem> </asp:RadioButtonList> <asp:Button ID="UploadButton" runat="server" Text="アップロード" onclick="UploadButton_Click" /> </div> <div> <hr /> <asp:Button ID="RefreshButton" runat="server" Text="サムネイル表示" onclick="RefreshButton_Click" /> <br /><br /> <asp:DataList ID="DataList1" runat="server" RepeatColumns="4" RepeatDirection="Horizontal"> <ItemTemplate> <asp:Image ID="Image1" runat="server" ImageUrl='<%# Eval("Url") %>' /> *2 </ItemTemplate> </asp:DataList> </div> </form> </body> </html>
RadioButtonListコントロールには、サムネイル画像作成時のオプション項目を示す3つのListItemコントロールを追加します(*1)。また、サムネイル画像の一覧表示用として、DataListコントロールのItemTemplateにはImageコントロールを追加します(*2)。
以上で、画面のUIが完成しました。