.net MVCでSignalRを使う。ちょっとはまったりもしたのでメモメモ。

とりあえず導入は、Nugetで「SignalR」をインストール。そしたらStartupのConfigurationしてる奴に以下を追加。

public void Configuration(IAppBuilder app)
{
    app.MapSignalR();//←これを追加
}

そしたら、Hubを作る。どこでもいいっぽいけど、Hubsってフォルダを作ってやった場合。

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;

namespace Hoge.Hubs
{
    [HubName("hogehub")]
    public class HogeHub : Hub
    {
        public void Send(string text)
        {
            Clients.All.HogeShortInfo(text);
        }
    }
}

次はView側。↓の感じ。コメント送信したら皆に飛ぶ感じのよくあるやつ。


<div>
    <input type="text" value="" id="message"/><input type="button" id="sendBtn" value="Send"/>
</div>
<div id="messageDiv">

</div>

<script src="~/Scripts/jquery.signalR-2.2.0.min.js">
<script src="/signalr/hubs">
<script type="text/javascript">
    $(function () {
        var echo = $.connection.hogehub;
        echo.on("HogeShortInfo", function (text) {
            $('#messageDiv').append(text);
        });
        $.connection.hub.start().done(function () {
            $('#sendBtn').click(function () {
                var msg = $('#message').val();
                echo.server.send(msg).done(function () {
                    $('#message').val("");
                });
            });
        });
    });
</script>

一個はまったのが、「signalr/hubs」。この子は動的に作られるらしく探しても出てこない。 ってとこまではいいんだけど、作られる階層がサイトのトップらしく、少し階層いったところのページでやる場合は「src="/signalr/hubs"」って頭に"/"をつけておかないと読み込んでくれない。大部分のサンプルは"signalr/hubs"ってなってるのでちょっとはまる。。。

ついで、小文字と大文字。基本的に小文字しか使えないと思ってたほうがいいのかしら。。。

で、書き方は何種類かあるっぽい。クライアント側のメソッドを定義するのは↓の2つの感じ。

        echo.on("HogeShortInfo", function (text) {
            $('#messageDiv').append(text);
        });
        echo.client.HogeShortInfo= function (text) {
            $('#messageDiv').append(text);
        });

個人的には上の書き方の方が、割り当ててますって感じがして好き。

あと、$.connection.hub.start().done()の中にイベントハンドラ入れとかないと、 接続する前にボタンとか押されてダメになるらしい。試してないけど作った人がそう言ってんだからそうしておきましょう。

って、ここまでは割と見かける。このやり方はチャットみたいな送信って押してみんなにいくみたいな場合。そーじゃなくて、サーバ側から何らかのイベント時に(Hubの外から)全体に送信したい場合はクライアントの呼び出しを下の感じで書く。

var hubContext = GlobalHost.ConnectionManager.GetHubContext<Hubs.HogeHub>();
hubContext.Clients.All.HogeShortInfo("なんか周知");

HogeShortInfoのところは、クライアントで割り当てた関数名を指定する感じ。↑のやつはコントローラーでもモデル側でも入れられるけど、↓のusingが必要。

using Microsoft.AspNet.SignalR;

で、サーバ側から任意のタイミングでクライアントの画面にメッセージ表示するみたいなのが↑ので出来るようになるんだけど、クライアント側のJavaScriptでもちょっとはまった。

    $(function () {
        var echo = $.connection.hogehub;
        echo.on("HogeShortInfo", function (text) {
            $('#messageDiv').append(text);
        });
        $.connection.hub.start();//←これが必須!!!
    });

「$.connection.hub.start();」これを入れないと動かない。

あと、サーバから返すデータは普通にJsonっぽいので↓の感じのオブジェクト作って返してあげてクライアント側で使ったりしやすい。

[System.Runtime.Serialization.DataContract]
public class TestHubJsonData
{
    [System.Runtime.Serialization.DataMember()]
    public int recid = 0;
    [System.Runtime.Serialization.DataMember()]
    public string state = "";
    [System.Runtime.Serialization.DataMember()]
    public string date = "";
}

下の感じで使用。オブジェクトの配列で返してもよきかな。

echo.on("TestDisp", function (data) {
    alert(data.date);
})