前回 でSignalRの概要とVisual Studioを利用した開発の準備が整いましたので、実際に簡単なSignalRアプリケーションを開発してみます。
サンプルとしてはnode.jsの回と同じ1行チャットアプリケーションです。同じ機能を出来るだけ同じメソッド名、パラメータ名で実装しますので、node.js + socket.ioとSignalRのスタイルの違いを感じていただければと思います。
プロジェクトを作成
まずはVisual Studioを立ち上げて「ファイル」 →「 新規」 →「 新規プロジェクト」の順に選択すると、以下のようなプロジェクトテンプレートを選択するダイアログが表示されます。
図1 新規プロジェクト作成ダイアログでは「ASP.NET 空のWebアプリケーション」を選ぶ
左ペインから「インストール済み」 →「 Visual C#」 →「 Web」の順に選択し、中央に表示されるテンプレートの中から「ASP.NET 空のWebアプリケーション」を選択します。そして下部にある「名前」は何でもよいのですが、今回は「Gihyo.SignalR」と入力しておきました。
プロジェクトが作成出来たらSignalRをインストールするために、ソリューションエクスプローラーのプロジェクト名を右クリックして表示されるメニューから「NuGetパッケージの管理」を選択してください。
図2 右クリックで表示されるメニューから「NuGetパッケージの管理」を選ぶ
選択すると以下のようなダイアログが表示されますので、右上にあるテキストボックスに「SignalR」と入力してEnterキーを押します。すると中央部分に検索結果が表示されるので、その中にある「Microsoft ASP.NET SignalR」を選択して表示される「インストール」ボタンをクリックします。
図3 「 SignalR」で検索した際の結果表示
これだけの作業で作成したプロジェクトにSignalRのインストールが完了しました。それではこれからは実際にコードを書いていきたいと思います。
サーバを実装
まずはプロジェクトを右クリックして「Hubs」フォルダを作成します。SignalRでは通例的にHubsフォルダを作成して、その中にHubの実装クラスを作成するようになっています。今回はChatHubという名前のクラスをHubsフォルダ内に作成しました。
そして実際に作成したChatHub.csファイルを開いて、以下のようにコードを追加します。
[HubName("chat")]
public class ChatHub : Hub
{
public void SendMessage(string text)
{
Clients.All.ReceiveMessage(text, DateTime.Now.ToLongTimeString());
}
}
socket.ioを使ったときのコードと比較してみてください。クライアントへのデータの渡し方が異なっていたり、引数として入力された文字列を受け取っていたり違いがありますね。
サーバ側のAPIの実装はこれで終わりなのですが、最後に作成したHubをシステムに登録する処理を追加する必要があります。ソリューションエクスプローラーのプロジェクト名を右クリックして「追加」 →「 グローバルアプリケーションクラス」を選択します。
図4 グローバルアプリケーションクラス(Global.asax)を追加する
途中でファイル名を入力するダイアログが表示されますが、デフォルトの「Global」のままで問題ないです。そして作成されたGlobal.asax.csファイルを開いて、中身を以下のように修正します。
using System;
using System.Web.Routing;
namespace Gihyo.SignalR
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHubs();
}
}
}
重要なのはMapHubメソッドで、このメソッドをアプリケーション開始時に呼び出しておかないと、クライアント側からHubのAPIを呼び出すことができません。
これでサーバ側の実装は全て終わりました。次はクライアント側の実装を行っていきます。
クライアントを実装
クライアント側はHTMLとJavaScriptで作成するので、テンプレート言語は何でもよいのですが、今回はASP.NETなのでWebフォームを使って作成していきます。
ソリューションエクスプローラーのプロジェクト名を右クリックして、「 追加」 →「 Web フォーム」を選択します。以下のような項目名を入力するダイアログが表示されるので、「 Default」と入力して「OK」ボタンをクリックします。
図5 ASP.NETのデフォルトファイル名を入力する
Webフォームを使うといっても、専用の記法を使う訳ではなくて、単純にHTMLの代わりとして使います。ファイルが作成できたら、以下のようにSignalR固有のJavaScriptコードを追加していきます。
<script src="Scripts/jquery-1.6.4.min.js"></script>
<script src="Scripts/jquery.signalR-1.0.0.min.js"></script>
<script>
$(function() {
var connection = $.hubConnection();
var chat = connection.createHubProxy("chat");
chat.on("ReceiveMessage", function (message, time) {
$("#chat").prepend("<li>" + time + ": " + message + "</li>");
});
$("#send").click(function () {
var text = $("#message").val();
$("#message").val("");
chat.invoke("SendMessage", text);
});
connection.start();
})
</script>
見た目自体もsocket.ioを使うコードと似ていると思います。SignalRはRPCとして通信を実装しているので、プロキシクラスを作成しているという点が大きく異なっています。
そして最後に表示用のタグを少しだけ追加します。Default.aspxファイルのbodyタグ内に以下のようなコードを追加します。
<div>
<h1>サンプルチャット</h1>
<input type="text" id="message" />
<input type="button" value="send" id="send" />
<ul id="chat"></ul>
</div>
node.jsの回ではJadeを使っていたので多少書き方は違いましたが、HTMLとしてはまったく同じ構造になっています。これですべての実装が終わったので、アプリケーションをデプロイする前に動作を確認しておきます。
Visual Studioでのデバッグは、ツールバーにあるブラウザ名のボタンをクリックするだけです。以下の例ではInternet Explorerが自動的に立ち上がります。
図6 デバッグ実行をInternet Explorerで行うボタン
ブラウザが立ち上がると作成したページが読み込まれるので、テキストボックスに文字列を入れて、「 send」ボタンをクリックしてメッセージが送信されることを確認します。
図7 作成したアプリケーションを実行した図
このようにSignalRでもnode.jsとsocket.ioで作ったアプリケーションと同じものが作れることがわかっていただけたかと思います。
それでは最後にnode.jsで作成したアプリケーションと同じく、Windows Azure Webサイトにデプロイしてみます。
アプリケーションをデプロイ
Windows Azure Webサイトを作成する手順に関しては、前々回のnode.jsのアプリケーションをデプロイするときとまったく同じですので、そちらを参考してください。
今回はすでにWebサイトが作成済みで、publishsettingsファイルがダウンロードも完了していることを前提にして説明を行います。ASP.NET and Web Tools 2012.2 をインストールしていない方はインストールを行ってから続きを行ってください。
それではソリューションエクスプローラーのプロジェクト名を右クリックして表示されるメニューから「発行」を選択します。すると以下のようなダイアログが表示されるので、「 インポート」ボタンをクリックしてダウンロード済みのpublishsettingsファイルを選択します。
図8 発行するための設定を行うダイアログ
インポートが完了するとpublishsettingsファイルを読み取って、発行に必要な情報を自動的に入力してくれるので、あとは右下にある「発行」ボタンをクリックするだけでWebサイトへデプロイが行われます。
完了すると自動的にブラウザが起動して、デプロイを行ったWebサイトが表示されるので、node.jsのときと同じようにタブを複製して動作を確認してみましょう。
図9 複数のタブ間でもリアルタイムでメッセージを受信可能
ちゃんと複数の画面を開いていても、メッセージが同時にすべての画面に配信されることが確認できます。
現在のWebサイトの仕様ではWebSocketにサーバが対応していないので、SignalRを使っている場合でも別の通信方式が利用されるようになっています。
これでnode.jsとSignalRの両方で作られたアプリケーションをクラウド上で実行することができましたので、次回はクラウドを利用する上で欠かせないスケールアウトについて、node.jsとSignalRの両方の視点からの解説と、node.jsとSignalRの違いや特徴についてまとめたいと思います。