読者です 読者をやめる 読者になる 読者になる

きよくらの備忘録

「三日坊主と呼ばせない!日記」改め。主にソフトウェア開発関連の話題。

AzureのWeb Role+SignalRでWebSocketを使ってみる

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 StudioSDKが入っていない場合、インストールしましょう。
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内でエラーが出る箇所があるので、そこは適当に削除してきましょう。



4.NuGetでSignalRを追加

SignalRで必要なものをNuGetで取ってきます。今回は『Microsoft.AspNet.SignalR』をインストールしてやります。



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のエミュレータが起動してデバッグ実行を行う事が出来ます。

6.デプロイ

動作確認が出来たらAzureにデプロイします。[Windows 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にしないといけない気がするため)。

*1:なにがやりたかったといういか、ちゃんとWebSocketが有効になっているのを試したかっただけなんでアレ。

*2:クライアント側もWebSocketが有効な場合

*3:対応する予定はあるという噂は聞くのですが

*4:リカバリーできると思いますがちょっと面倒かも

*5:どのみちセットアッパーからWebPIが起動してWebPI経由でインストールすることになります

*6:タイミングはここでなくてもよいです。デプロイするまでに作っておけば。