AzureのWeb RoleにSignalRで作ったサンプルをデプロイして、WebSocketで通信できることを確認してみました*1。
※念のため最初に書いておきますが、特別なことをしなければAzureでWebSocketが使えないわけではありません。通常のIISと.NET FramewrokのWebSocket対応状況の通りです。
SignalRではIIS8+.NET Framework 4.5の環境あれば、特に特別なことをしなくてもWebSocketが利用できます*2。これをWindow Azureで扱いたい場合、Azure Web Siteで使えると楽でよいのですが、2013年7月20日現在ではまだ対応していません*3。
そのため、AzureでWebSocketが有効な状態でSignalRのアプリをホストしようと思うと、『クラウドサービス(Web Role)』を使うか、『仮想マシン』で自分で2012 Serverの環境を構築してやる必要があります。
成るべく簡単にさくっと使えると便利なので、とりあえずWeb RoleでWebSocketが有効な状態でSignalRが使えるようにデプロイしてみました。
特に難しいところや特殊なところは無いのですが、一点だけ。『プロジェクト作成時に.NET Framework 4.5を選択する』こと。これだけ忘れないほうが後々面倒がないと思います*4。
せっかくなのでメモがてら、手順を最初から書いてみたいと思います。
1.Windows Azure SDK for .NET 2.0のインストール
Visual StudioにSDKが入っていない場合、インストールしましょう。
Web Platform Installerからインストールできます。もしくは、下記のリンクからセットアッパーをダウンロードしてインストールしてください*5。
Windows Azure SDK for .NET - 2.0
2.Azureでクラウドサービスを追加する
Azure上で、ホストするためのクラウドサービスを追加しておきます*6。
Azureのポータルにログインし、左下の新規追加ボタンなどから、[コンピューティング]−[クラウドサービス]−[簡易作成]等を選んで、必要な情報を入力して作成してください。
3.プロジェクトの作成
プロジェクトの新規作成を行います。この時、テンプレートは[<言語>]−[Cloud]−[Window Azure クラウドサービス]を選択し、ダイアログで『.NET Framework 4.5』を選択します。このフレームワークバージョンの選択を忘れないように。
クラウドサービスのテンプレートを選ぶダイアログでは、今回はとりあえず『ASP.NET Webロール』を選択しておきます。
テンプレートが展開されたら、WebRoleのプロジェクト内の不要なファイルを消しておきます。別にそのままでも構いませんが、どうせサンプルだし軽いほうが良いかな、と。
とりあえずこれだけ残っておけば十分でしょう。
なお、ここまで削除するとGlobal.asaxのApplication_Start内でエラーが出る箇所があるので、そこは適当に削除してきましょう。
5.SignalRのアプリケーションを実装
SignalRのサンプルアプリケーションを実装します。ボタンをおしたらエコーバックするだけの簡単なアプリケーションを実装します。
Hubクラスの実装:HelloHub.cs
namespace WebRole1 { [HubName("hello")] public class HelloHub : Hub { public void Hello( string name) { Clients.All.SayHello( "hello , " + name); } } }
Global.asaxのApplication_Startに追記
public class Global : HttpApplication { void Application_Start( object sender, EventArgs e) { RouteTable.Routes.MapHubs(); }
HTMLファイルの実装:index.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Hello SignalR</title> <script src="Scripts/jquery-1.8.2.min.js"></script> <script src="Scripts/jquery.signalR-1.1.2.min.js"></script> <script type="text/javascript"> $(function () { var connection = $.hubConnection(); var echo = connection.createHubProxy("hello"); echo.on("SayHello", function (text) { alert(text); }); $("#send").click(function () { var name = $("#name").val(); echo.invoke("Hello", name); }); connection.start(function () { $("#send").prop("disabled", false); }); }) </script> </head> <body> <form id="form1"> <div> 名前:<input type="text" id="name" /><br /> <input type="button" id="send" value="送信" disabled="disabled" /> </div> </form> </body> </html>
実装内容は@ITの芝村さんの記事ASP.NET SignalRを知るを参考に適当に実装したものになっています。SignalRの実装や解説については上記の記事や同じく芝村さんのリアルタイム Web 最前線 〜 Socket.IO & SignalR 徹底解説 [スライド&動画]やリアルタイムWebを極めるを参照されると良いと思います。
実装が出来たら、ローカルで実行して動作を確認して下さい。Azureのエミュレータが起動してデバッグ実行を行う事が出来ます。
7.動作確認
WebSocketが使われているかどうかを簡単に確認するには、Chromeを利用するのが簡単です。デベロッパーツールの[Network]タブを表示した状態でページを読み込んでみてください。以下のように「connect?transport=webSocket&connectionToken...」というエントリが見つかればWebSocketで通信されていることがわかります。
[追記]もしプロジェクト作成時に.NET 4.0で作った場合は
もし、プロジェクト作成時に.NET 4.0で作ってしまった場合も、
- フレームワークバージョンの変更
- ServiceConfiguration.Cloud.cscfgを編集し、ServiceConfiguration要素のosFamily属性を3にする
で対応できるかもしません。ただしこの時、すでにSignalR関連のNuGetパッケージを取り込んでいた場合、再度取り込みなおす必要がある可能性があります(パッケージ取込み時、targetFramework属性がnet40として読み込まれているものをnet45にしないといけない気がするため)。