チュートリアル: SignalR 2 と MVC 5 を使用したリアルタイムのチャット

このチュートリアルでは、ASP.NET SignalR 2 を使用してリアルタイムのチャット アプリケーションを作成する方法を示します。 SignalR を MVC 5 アプリケーションに追加し、メッセージを送信および表示するチャット ビューを作成します。

このチュートリアルでは、次の作業を行いました。

  • プロジェクトのセットアップ
  • サンプルの実行
  • コードを確認する

警告

このドキュメントは、最新版の SignalR を対象としていません。 ASP.NET Core SignalR に関する記事を参照してください。

前提条件

プロジェクトをセットアップする

このセクションでは、Visual Studio 2017 と SignalR 2 を使用して、空の ASP.NET MVC 5 アプリケーションの作成、SignalR ライブラリの追加、チャット アプリケーションの作成を行う方法について説明します。

  1. Visual Studio で、.NET Framework 4.5 を対象とする C# ASP.NET アプリケーションを作成し、「SignalRChat」という名前を付け、[OK] をクリックします。

    Create web

  2. [新しい ASP.NET Web アプリケーション - SignalRMvcChat] で、[MVC] を選択し、[認証の変更] を選択します。

  3. [認証の変更] で、[認証なし] を選択し、[OK] をクリックします。

    Select No Authentication

  4. [新しい ASP.NET Web アプリケーション - SignalRMvcChat] で、[OK] を選択します。

  5. ソリューション エクスプローラーで、プロジェクトを右クリックして、[追加]>[新しい項目] を選択します。

  6. [新しい項目の追加 - SignalRChat] で、[インストール済み]>[Visual C#]>[Web]>[SignalR] を選択して、[SignalR Hub クラス (v2)] を選択します。

  7. クラスに「ChatHub」 という名前を付けて、プロジェクトに追加します。

    この手順では、ChatHub.cs クラス ファイルを作成し、SignalR をサポートする一連のスクリプト ファイルとアセンブリ参照をプロジェクトに追加します。

  8. 新しい ChatHub.cs クラス ファイル内のコードを次のコードに置き換えます。

    using System;
    using System.Web;
    using Microsoft.AspNet.SignalR;
    namespace SignalRChat
    {
        public class ChatHub : Hub
        {
            public void Send(string name, string message)
            {
                // Call the addNewMessageToPage method to update clients.
                Clients.All.addNewMessageToPage(name, message);
            }
        }
    }
    
  9. ソリューション エクスプローラーで、プロジェクトを右クリックして、[追加]>[クラス] を選択します。

  10. 新しいクラスに「Startup」という名前を付け、プロジェクトに追加します。

  11. Startup.cs クラス ファイル内のコードを次のコードに置き換えます。

    using Owin;
    using Microsoft.Owin;
    [assembly: OwinStartup(typeof(SignalRChat.Startup))]
    namespace SignalRChat
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                // Any connection or hub wire up and configuration should go here
                app.MapSignalR();
            }
        }
    }
    
  12. ソリューション エクスプローラーで、[コントローラー]>[HomeController.cs] を選択します。

  13. このメソッドを HomeController.cs に追加します。

    public ActionResult Chat()
    {
        return View();
    }
    

    このメソッドは、後の手順で作成するチャット ビューを返します。

  14. ソリューション エクスプローラーで、[ビュー]>[ホーム] を右クリックし、[ビューの>追加] を選択します。

  15. [ビューの追加] で、新しいビューに「Chat」という名前を付け、[追加] を選択します。

  16. Chat.cshtml の内容を次のコードに置き換えます。

    @{
        ViewBag.Title = "Chat";
    }
    <h2>Chat</h2>
    <div class="container">
        <input type="text" id="message" />
        <input type="button" id="sendmessage" value="Send" />
        <input type="hidden" id="displayname" />
        <ul id="discussion">
        </ul>
    </div>
    @section scripts {
        <!--Script references. -->
        <!--The jQuery library is required and is referenced by default in _Layout.cshtml. -->
        <!--Reference the SignalR library. -->
        <script src="~/Scripts/jquery.signalR-2.1.0.min.js"></script>
        <!--Reference the autogenerated SignalR hub script. -->
        <script src="~/signalr/hubs"></script>
        <!--SignalR script to update the chat page and send messages.--> 
        <script>
            $(function () {
                // Reference the auto-generated proxy for the hub.  
                var chat = $.connection.chatHub;
                // Create a function that the hub can call back to display messages.
                chat.client.addNewMessageToPage = function (name, message) {
                    // Add the message to the page. 
                    $('#discussion').append('<li><strong>' + htmlEncode(name) 
                        + '</strong>: ' + htmlEncode(message) + '</li>');
                };
                // Get the user name and store it to prepend to messages.
                $('#displayname').val(prompt('Enter your name:', ''));
                // Set initial focus to message input box.  
                $('#message').focus();
                // Start the connection.
                $.connection.hub.start().done(function () {
                    $('#sendmessage').click(function () {
                        // Call the Send method on the hub. 
                        chat.server.send($('#displayname').val(), $('#message').val());
                        // Clear text box and reset focus for next comment. 
                        $('#message').val('').focus();
                    });
                });
            });
            // This optional function html-encodes messages for display in the page.
            function htmlEncode(value) {
                var encodedValue = $('<div />').text(value).html();
                return encodedValue;
            }
        </script>
    }
    
  17. ソリューション エクスプローラーで、[スクリプト] を展開します。

    jQuery と SignalR のスクリプト ライブラリがプロジェクトに表示されます。

    重要

    パッケージ マネージャーを使用すると、SignalR スクリプトの新しいバージョンをインストールできます。

  18. コード ブロック内のスクリプト参照が、プロジェクト内のスクリプト ファイルのバージョンに対応していることを確認します。

    元のコード ブロックからのスクリプト参照:

    <!--Script references. -->
    <!--The jQuery library is required and is referenced by default in _Layout.cshtml. -->
    <!--Reference the SignalR library. -->
    <script src="~/Scripts/jquery.signalR-2.1.0.min.js"></script>
    
  19. 一致しない場合は、.cshtml ファイルを更新してください。

  20. メニュー バーから、[ファイル]>[すべてを保存] の順に選択します。

サンプルを実行する

  1. ツールバーの [スクリプト デバッグ] をオンにして、再生ボタンを選択し、サンプルをデバッグ モードで実行します。

    Enter user name

  2. ブラウザーが開いたら、チャット ID の名前を入力します。

  3. ブラウザーから URL をコピーして、ブラウザーを 2 つ新たに開き、URL をアドレス バーに貼り付けます。

  4. 各ブラウザーで、それぞれ一意の名前を入力します。

  5. 名前の入力後、コメントを追加し、[送信] を選択します。 他のブラウザーでこれを繰り返します。 コメントはリアルタイムで表示されます。

    Note

    このシンプルなチャット アプリケーションは、サーバー上のディスカッション コンテキストを保持しません。 ハブは、現在のすべてのユーザーにコメントをブロードキャストします。 後でチャットに参加したユーザーには、参加した時点から追加されたメッセージが表示されます。

    チャット アプリケーションが 3 つの異なるブラウザーでどのように動作するかを確認します。 Tom、Anand、および Susan がメッセージを送信すると、すべてのブラウザーがリアルタイムで更新されます。

    All three browsers display the same chat history

  6. ソリューション エクスプローラーで、実行中のアプリケーションの [スクリプト ドキュメント] ノードを調べます。 SignalR ライブラリが実行時に生成する「hubs」という名前のスクリプト ファイルがあります。 このファイルは、jQuery スクリプトとサーバー側コード間の通信を管理します。

    autogenerated hubs script in the Script Documents node

コードを確認する

SignalR チャット アプリケーションは、2 つの基本的な SignalR 開発タスクを示します。 ハブを作成する方法を示します。 サーバーは、そのハブをメインの調整オブジェクトとして使用します。 ハブは SignalR jQuery ライブラリを使用してメッセージを送受信します。

ChatHub.cs の SignalR ハブ

コード サンプルでは、ChatHub クラスは Microsoft.AspNet.SignalR.Hub クラスから派生します。 Hub クラスからの派生は、SignalR アプリケーションを構築するのに便利な方法です。 ハブ クラスにパブリック メソッドを作成し、Web ページ内のスクリプトからそれらのメソッドを呼び出してアクセスできます。

チャット コードでは、クライアントは ChatHub.Send メソッドを呼び出して新しいメッセージを送信します。 ハブは次に、Clients.All.addNewMessageToPage を呼び出すことによってすべてのクライアントにメッセージを送信します。

この Send メソッドは、いくつかのハブの概念を示しています。

  • クライアントがパブリック メソッドを呼び出すことができるように、ハブでそのメソッドを宣言します。

  • Microsoft.AspNet.SignalR.Hub.Clients 動的プロパティを使用して、このハブに接続されているすべてのクライアントと通信します。

  • クライアントで関数 (addNewMessageToPage 関数など) を呼び出して、クライアントを更新します。

    public class ChatHub : Hub
    {
        public void Send(string name, string message)
        {
            Clients.All.addNewMessageToPage(name, message);
        }
    }
    

SignalR と jQuery Chat.cshtml

コード サンプルの Chat.cshtml ビュー ファイルは、SignalR jQuery ライブラリを使用して SignalR ハブと通信する方法を示しています。 このコードでは、多くの重要なタスクが実行されます。 ハブの自動生成されたプロキシへの参照を作成し、サーバーがクライアントにコンテンツをプッシュするために呼び出すことができる関数を宣言し、ハブにメッセージを送信するための接続を開始します。

var chat = $.connection.chatHub;

Note

JavaScript では、サーバー クラスとそのメンバーへの参照は camelCase で記述します。 このコード サンプルでは、JavaScript で C# ChatHub クラスを chatHub として参照します。

このコード ブロックでは、スクリプトにコールバック関数を作成します。

chat.client.addNewMessageToPage = function (name, message) {
    // Add the message to the page. 
    $('#discussion').append('<li><strong>' + htmlEncode(name) 
        + '</strong>: ' + htmlEncode(message) + '</li>');
};

サーバー上のハブ クラスは、この関数を呼び出して、各クライアントにコンテンツの更新をプッシュします。 htmlEncode 関数の省略可能な呼び出しは、メッセージをページに表示する前にその内容を HTML エンコードする方法を示しています。 これは、スクリプトの挿入を防ぐ方法です。

このコードにより、ハブとの接続が開きます。

$.connection.hub.start().done(function () {
    $('#sendmessage').click(function () {
        // Call the Send method on the hub. 
        chat.server.send($('#displayname').val(), $('#message').val());
        // Clear text box and reset focus for next comment. 
        $('#message').val('').focus();
    });
});

Note

この方法により、イベント ハンドラーを実行する前に接続を確立できます。

このコードは接続を開始し、[チャット] ページの [送信] ボタンのクリック イベントを処理する関数を渡します。

コードを取得する

完成したプロジェクトのダウンロード

その他のリソース

SignalR の詳細については、次のリソースを参照してください。

次のステップ

このチュートリアルでは、次の作業を行いました。

  • プロジェクトのセットアップ
  • サンプルを実行しました
  • コードを調べました

次の記事では、ASP.NET SignalR 2 を使用して高周波メッセージング機能を提供する Web アプリケーションを作成する方法について説明します。