読者です 読者をやめる 読者になる 読者になる

kikki's tech note

技術ブログです。UnityやSpine、MS製品など技術色々について解説しています。

WebSocket (SignalR) の導入

前稿、リアルタイムウェブアプリの開発に必要な環境を導入しました。
本稿では簡単なウェブアプリとして、チャットツールを作るために、SignalRの導入方法について確認します。

SignalRとは

SignalRは、マイクロソフトが中心となり開発された、リアルタイムウェブアプリ機能を追加するライブラリです。SignalRでは、WebSocketをサポートしていますが、サポートされていないブラウザ上でも動作するよう構成されています。SignalRは、ASP.NET技術と非常に親和性が高く、実装工数も少ないため、.NET開発にとって非常に優位性があります。是非、利用してみてください。

次章から実装方法について、サンプルを交えて解説します。

プロジェクトファイルの準備

まず、プロジェクト全体の構成について確認します。本稿は、以下の図の通り、プロジェクトに必要なファイルを最低限準備します。
f:id:kikkisnrdec:20150605114852p:plain

上記ファイル群の中でも以下のファイルが必須となります。

  • ChatHub.cs
  • Startup.cs

その他のファイルについては、実装するサービスに応じて準備して下さい。

フロントエンドの実装

まず、チャットツールを表示させるの画面を準備します。MVCフレームワークでの「Controller」・「View」に該当する処理を実装します。
[HomeController.cs]

using System.Web.Mvc;

namespace Socket.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    }
}

[Index.cshtml]

<html>
<head>
    <title>Chat Tool</title>
</head>
<body>
    <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>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
    <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/signalr/jquery.signalr-2.0.3.min.js"></script>
    <!-- ①SignalRのURIマッピング先を指定 -->
    <script src="~/signalr/hubs"></script>
    <script>
        $(function () {
            // ②通信先として「ChatHub.cs」で定義されたハブクラス「ChatHub」を指定
            var chat = $.connection.chatHub;
            // ③サーバー側から「addNewMessageToPage」メソッドが呼び出された際に実行
            chat.client.addNewMessageToPage = function (name, message) {
                $('#discussion').append('<li><strong>' + htmlEncode(name)
                    + '</strong>: ' + htmlEncode(message) + '</li>');
            };
            $('#displayname').val(prompt('Enter your name:', ''));
            $('#message').focus();
            // ④ソケット通信を開始
            $.connection.hub.start().done(function () {
                $('#sendmessage').click(function () {
                    // ⑤サーバー側の「Send」メソッドへとデータを送信
                    chat.server.send($('#displayname').val(), $('#message').val());
                    $('#message').val('').focus();
                });
            });
        });
        function htmlEncode(value) {
            var encodedValue = $('<div />').text(value).html();
            return encodedValue;
        }
    </script>
</body>
</html>

ここで重要な要素として、以下の要素があります。

  • html側でソケット通信を開始する際に、③のように、どの通信処理を実行するかを事前に決めておくこと
  • Socket通信関連処理の名前は、「ローワーキャメルケース」で定義すること

これで、画面の準備が整いました。

バックエンド(サーバー側の処理)の実装

次に、バックエンド側の処理を準備します。
[ChatHub.cs]

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

namespace Socket.Hubs
{
    // jsから呼び出されるハブの名前を定義
    [HubName("chatHub")]
    public class ChatHub : Hub
    {
        // jsから呼び出される処理を実装
        public void Send(string name, string message)
        {
            // どのクライアントにレスポンスを返すか指定
            // ※ここでは全クライアントに返す
            Clients.All.addNewMessageToPage(name, message);
        }
    }
}

[Startup.cs]

using Microsoft.Owin;
using Owin;

// SignalRをサーバー上に稼働
[assembly: OwinStartup(typeof(SignalRHubServer.Startup))]
namespace SignalRHubServer
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // URIマップ先を設定
            app.MapSignalR();
        }
    }
}

ここでの重要な要素として、以下の要素があります。

  • レスポンス先を指定すること (全員か特定のグループか)
  • フロント側で指定したURIと合うよう、URIマッピングを正しく合わせること
  • Socket通信関連処理の名前は、「ローワーキャメルケース」で定義すること

これで、サーバー側の処理の実装は完了しました。

次回では、フロントエンド側でのインタラクティブな画面反映処理を実装していきます。

※無断転載禁止 Copyright (C) 2015 kikkisnrdec All Rights Reserved.