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

このチュートリアルでは、SignalR を使ってリアルタイム チャット アプリケーションを作成する方法を示します。 SignalR を空の ASP.NET Web アプリケーションに追加し、メッセージの送信と表示を行う HTML ページを作成します。

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

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

警告

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

前提条件

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

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

  1. Visual Studio で、ASP.NET Web アプリケーションを作成します。

    Create web

  2. [新しい ASP.NET プロジェクト - SignalRChat] ウィンドウで、[空] が選択された状態のまま、[OK] を選びます。

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

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

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

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

  6. 新しい 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 broadcastMessage method to update clients.
                Clients.All.broadcastMessage(name, message);
            }
        }
    }
    
  7. ソリューション エクスプローラーで、プロジェクトを右クリックして、[追加]>[新しい項目] を選択します。

  8. [新しい項目の追加 - SignalRChat] で、[インストール済み]>[Visual C#]>[Web] を選んで、[OWIN Startup クラス] を選びます。

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

  10. Startup クラスの既定のコードを次のコードに置き換えます。

    using Microsoft.Owin;
    using 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();
            }
        }
    }
    
  11. ソリューション エクスプローラーで、プロジェクトを右クリックして、[追加]>[HTML ページ] を選択します。

  12. 新しいページに「index」という名前を付けて、[OK] を選びます。

  13. ソリューション エクスプローラーで、作成した HTML ページを右クリックして [スタート ページに設定] を選びます。

  14. HTML ページの既定のコードを次のコードに置き換えます。

    <!DOCTYPE html>
    <html>
    <head>
        <title>SignalR Simple Chat</title>
        <style type="text/css">
            .container {
                background-color: #99CCFF;
                border: thick solid #808080;
                padding: 20px;
                margin: 20px;
            }
        </style>
    </head>
    <body>
        <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>
        <!--Script references. -->
        <!--Reference the jQuery library. -->
        <script src="Scripts/jquery-3.1.1.min.js" ></script>
        <!--Reference the SignalR library. -->
        <script src="Scripts/jquery.signalR-2.2.1.min.js"></script>
        <!--Reference the autogenerated SignalR hub script. -->
        <script src="signalr/hubs"></script>
        <!--Add script to update the page and send messages.--> 
        <script type="text/javascript">
            $(function () {
                // Declare a proxy to reference the hub. 
                var chat = $.connection.chatHub;
                // Create a function that the hub can call to broadcast messages.
                chat.client.broadcastMessage = function (name, message) {
                    // Html encode display name and message. 
                    var encodedName = $('<div />').text(name).html();
                    var encodedMsg = $('<div />').text(message).html();
                    // Add the message to the page. 
                    $('#discussion').append('<li><strong>' + encodedName
                        + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</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();
                    });
                });
            });
        </script>
    </body>
    </html>
    
  15. ソリューション エクスプローラーで、[スクリプト] を展開します。

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

    重要

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

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

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

    <!--Script references. -->
    <!--Reference the jQuery library. -->
    <script src="Scripts/jquery-3.1.1.min.js" ></script>
    <!--Reference the SignalR library. -->
    <script src="Scripts/jquery.signalR-2.2.1.min.js"></script>
    
  17. 一致しない場合は、.html ファイルを更新します。

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

サンプルを実行する

  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

コードを確認する

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

ChatHub.cs の SignalR ハブ

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

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

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

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

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

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

    public class ChatHub : Hub
    {
        public void Send(string name, string message)
        {
            // Call the broadcastMessage method to update clients.
            Clients.All.broadcastMessage(name, message);
        }
    }
    

index.html の SignalR と jQuery

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

var chat = $.connection.chatHub;

Note

JavaScript では、サーバー クラスとそのメンバーへの参照をキャメル ケースで記述する必要があります。 コード サンプルの JavaScript では、C# の ChatHub クラスを chatHub として参照しています。

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

chat.client.broadcastMessage = function (name, message) {
        // Html encode display name and message. 
        var encodedName = $('<div />').text(name).html();
        var encodedMsg = $('<div />').text(message).html();
        // Add the message to the page. 
        $('#discussion').append('<li><strong>' + encodedName
            + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
    };

サーバー上のハブ クラスは、この関数を呼び出して、各クライアントにコンテンツの更新をプッシュします。 表示する前にコンテンツを HTML でエンコードする 2 行は省略可能であり、スクリプト インジェクションを防ぐためのよい方法として示してあります。

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

$.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

この方法を使うと、イベント ハンドラーが実行する前にコードによって接続が確立されます。

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

コードを取得する

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

その他のリソース

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

次のステップ

このチュートリアルでは、次のことを行います。

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

次の記事に進んで、SignalR と MVC 5 を使う方法を学習してください。