だるろぐ

明日できることは、今日しない。

SignalR Deep Dive ! に参加してきた+WebMatrix で SignalR 動かしてみた

f:id:daruyanagi:20120830191311j:plain

仕事を少し早くあがって、 @shibayan のリサイタルに参加してきました。最近ずっと眠れなくて、仕事中もずっと眠い状態だったけれど、結構面白かったので寝落ちせずにすんだよ(ぉ



Video streaming by Ustream

興味ある人は USTREAM をご覧あれ。わしもよくわからんけど、とりあえず SignalR (http://signalr.net/)というのは、

  • ASP.NET テクノロジをベースとした
  • 非同期でリアルタイムな
  • サーバーとクライアントの双方向通信

を実現するライブラリ、ってことでいいのかな。サーバーとクライアントの通信で利用される技術は、 SignalR が勝手にチョイスしてくれるみたい(モダンな環境なら WebSocket を、クラシカルな環境だったらポーリングを、ってな感じ)。詳しくはエロいひと、じゃなくて偉いひとに聞いて欲しい。

ともあれ、忘れないうちにこれを WebMatrix で使ってみる。

サーバー側のコード

# ~/App_Code/SampleHub.cs

using SignalR.Hubs; // <-- NuGet でインストールしる!

[HubName("sample")] // <-- あとで createProxy("sample") と使う
public class SampleHub : Hub
{
    private static string _message = "";

    private string Message
    {
        get { return _message; }
        set
        {
            _message = value;

            // 接続中のクライアントすべてに Echo() 命令を送る
            Clients.Echo(_message);

            // そのほかにも
            // Caller.Echo(); 呼び出したクライアントに命令
            // Groups["Hoge"].Echo(); クライアントグループに命令
            // がある
        }
    }

    public void Add(string s)// <-- ちゃんと公開しろよ
    {
        Message += s;
    }

    public void Clear()
    {
        Message = "";
    }
}

まずは、 Hub というものを作る。今回は文字列(Message)を足す関数(Add)と、クリアする関数(Clear)を用意した。文字列が更新されるとクライアントにその結果を表示するように命令(Echo)する。これがサーバー側の処理。

クライアント側のコード

# Default.cshtml

<!DOCTYPE html>

@{
    
}

<html lang="ja">
    <head>
        <meta charset="utf-8" />
        <title>マイ サイトのタイトル</title>
        <script type="text/javascript"
                src="Scripts/jquery-1.6.4.js"></script>
        <script type="text/javascript"
                src="Scripts/jquery.signalR-0.5.3.js"></script>
        <script>
            // 接続を取得
            var connection = $.hubConnection();

            // sample ハブ(のプロキシ)を取得
            var sample = connection.createProxy("sample");

            // 接続開始(忘れたらしばやんみたいにエラー出るで)
            connection.start();

            // sample ハブの Echo() 命令を受け取ったら……
            sample.on("Echo", function (value) {
                $("#value").html(value);
            });
        </script>
    </head>
    <body>
        <p id="value"></p>
        <input type="button"
               onclick="sample.invoke('Add', 'foobar');"
               id="add" name="add" value="add" />
        <input type="button"
               onclick="sample.invoke('clear');"
               id="clear" name="clear" value="clear" />
    </body>
</html>

クライアント側の処理は次のような感じ。

[クライアント]ボタンクリックで sample ハブの Add/Clear を呼ぶ
→ [サーバー]sample ハブが接続中のクライアントへ Echo() をブロードキャスト
→ [すべてのクライアント]#value が更新される

というカラクリ。

結果

f:id:daruyanagi:20120831025740p:plain

3つブラウザーを起動し、そのうち1つのブラウザーでボタンを押すと、ほかも全部いっぺんに更新される! これはちょっと楽しいな。