HTML5の普及に従って、通常のWebアプリにもリッチさや、リアルタイム性が求められるようになってきた。
HTTPプロトコルを使ってサーバからクライアントに通知する仕組みとしては、以前はCometなどの技術が使われていた。しかしながらCometはロング・ポーリング*により疑似的にクライアント/サーバ間の双方向通信を実現しているため、HTTPのコネクションを長時間専有するなどの問題もあった。
* HTTP接続をつないだままの状態で保持しておき、サーバから送信したいタイミングではじめてレスポンスを返す。
このような用途に対応するべく、W3CとIEFTによりWebサーバとクライアントの間で双方向通信するための規格としてWebSocketプロトコルが策定されている。WebSocketでは、一度コネクションを接続した後は、必要な情報のやり取りをそのコネクション上で行うため、HTTP上の疑似プロトコルに比べて効率よく通信を行うことができる。
ASP.NET 4.5からはWebSocketプロトコルの対応も含まれるようになり、ASP.NETで実装したWebアプリでもWebSocketを使ったクライアント/サーバ間の双方向通信を実現できるようになった。
SignalR(シグナルアール)は、マイクロソフトからオープンソースで公開されているライブラリで、複数のクライアントに対して非同期での双方向通信をサポートする。SignalRは、もともとは独立したライブラリとして開発されていたが、ASP.NET 2012 Fall UpdateのRC版からASP.NETの一部として組み込まれ、ASP.NET and Web Tools 2012.2で正式にバージョン1.0となった。
実際のWebアプリでは、複数のブラウザに対応させる必要が出てくるため、場合によってはWebSocketプロトコルに対応していないブラウザもサポートする必要がある。このため、SignalRはWebSocketに対応していない場合にはロング・ポーリングなどの別の方法を使って双方向通信を実現している。同様のライブラリとしては、Node.jsで動作するSocket.IOがある。
ここからは、SignalRを使った簡単なチャット・アプリのコードを見ながら双方向通信を実装する例を説明する。
今回作成するチャット・アプリは、次の画面で示すように名前とメッセージを入力するフィールドを持ち、[送信]ボタンの押下によって、接続している全てのクライアントに名前とメッセージが送信される。
まずはプロジェクトを作成するが、シンプルな構成を採るため、「ASP.NET 空の Web アプリケーション」テンプレートを(プロジェクトの新規作成時に)選択する。この最終リリースからはSignalRが標準でインストールされているため、別途ライブラリ・パッケージ・マネージャでインストールする必要はない。
このサンプルでは次の3つのファイルを作成する。
種類 | 用途 |
---|---|
Global Application Class | アプリ起動時にSignalRのHub(後述)を登録 |
SignalR Hub Class | クライアントから受け取ったメッセージを全てのクライアントに通知 |
HTML Page | 入力したメッセージをHubへ送信 |
サンプルで作成するファイル |
SignalRではサーバ側を実装する際に、PersistentConnection(=http上でSignalRサービスを公開するためのAPIを持つ基本クラス)を使う方法と、Hubを使う方法の2種類がある。
PersistentConnectionによる方法は、呼び出しディスパッチを開発者が実装する必要があるが、低レベルでの実装が可能になる。それに対してHubによる方法は、PersistentConnection上に実装されたRPC(リモート・プロシージャ・コール)フレームワークで、クライアント/サーバ間での呼び出しメソッドを簡単に定義できる。今回の例では、サーバ側にHubを使う例を紹介する。
まずは、GlobalクラスのApplication_Startメソッドで、アプリ開始時に、「(クライアントからアクセスされる)Hub」のルーティング情報を登録する。デフォルトでは「/signalr」として登録される。
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
// デフォルトのhubsのルーティングを登録する : ~/signalr
RouteTable.Routes.MapHubs();
}
……省略……
}
次にサーバ側の処理を実装するクラスを見ていく。今回はHubクラスから継承したChatHubクラスを作成する(次のコードを参照)。publicメソッドとして定義すると、そのままクライアントから呼び出せるようになる。
public class ChatHub : Hub
{
public void Send(string name, string message)
{
// 全てのクライアントに対して受信したメッセージを通知する
Clients.All.broadcastMessage(name, message);
}
}
このコード例では、クライアントから引数としてnameとmessageを渡されるSendメソッドが定義してある。ここではHubに接続している全てのクライアントに対してブロードキャスト・メッセージを送信している。
最後にクライアントの処理を見ていく。SignalRにはJavaScriptと.NETのクライアント側ライブラリが用意されているが、今回はJavaScriptライブラリを使用する。クライアント側の処理をHTMLとJavaScriptのコードで定義している。
<!DOCTYPE html>
<html>
:
<body>
<div>
お名前:<input type="text" id="name" />
一言:<input type="text" id="message" />
<input type="button" id="send" value="送信" />
</div>
<div>
<ul id="messages" />
</div>
<!-- jQueryライブラリ -->
<script src="Scripts/jquery-1.6.4.min.js" ></script>
<!-- (1)SignalRライブラリ -->
<script src="Scripts/jquery.signalR-1.0.0-rc2.js"></script>
<!-- (2)自動生成されたSignalR Hubを指定する -->
<script src="/signalr/hubs"></script>
<!-- クライアント側実装:Hubから送信されたメッセージの受け取りと、Hubへの送信処理 -->
<script type="text/javascript">
$(function () {
// (3)ChatHubオブジェクトへの参照
var chat = $.connection.chatHub;
// (4)Hubが送信したブロードキャスト・メッセージを受け取るハンドラ
chat.client.broadcastMessage = function (name, message) {
// 受信した名前とメッセージをエンコード
var encodedName = $('<div />').text(name).html();
var encodedMsg = $('<div />').text(message).html();
// 受信した名前とメッセージをリストに追加
$('#messages').append('<li>' + encodedName + ' さんの発言: ' + encodedMsg + '</li>');
};
// 最初にメッセージ入力にフォーカスを設定
$('#message').focus();
// コネクション開始
$.connection.hub.start().done(function () {
$('#send').click(function () {
// (5)メッセージを取得しChatHubオブジェクトのsendメソッドを呼び出す
chat.server.send($('#name').val(), $('#message').val());
// メッセージをクリアしフォーカスを設定する
$('#message').val('').focus();
});
});
});
</script>
</body>
</html>
クライアント側のJavaScriptコードでは、まずjQueryとSignalR拡張ライブラリ(1)ファイルをインクルードする。
<script>タグで「/signalr/hubs」を指定すると(2)、サーバ側で定義したHubをクライアント側で参照(3)できるようにプロキシが動的に生成される。
サーバからクライアントへの通知は、{hub}.client.{メソッド}に対するコールバックとして定義できる。上記の例では、(4)のようにnameとmessageを引数としてブロードキャスト・メッセージとして受け取るコールバックを指定している。
クライアントからサーバのメソッド呼び出しは、(5)のように、{hub}.client.{メソッド}の形式で記述することができる。
第1回目はVisual Studio 2012の新機能とASP.NET 4.5のコア機能の中から主だったものを紹介した。HTML5への対応やセキュリティ、パフォーマンス向上など、誰もが使う機能に対する強化は多くの開発者の助けになるだろう。
次回はWebフォームに焦点を当てて、新しいモデル・バインディング、HTML5への対応などについて紹介する予定である。
Copyright© Digital Advantage Corp. All Rights Reserved.