SQL

【開発してみた】ASP.NET Core X SignalR でリアルタイムチャットを10分で開発してみた

「開発してみた」シリーズ第1弾です。

なんでも作ってみないと理解が深まらない、ということで、色々サクッと作っていきます。

それでは、ライブチャットを構築していきます。


目次[非表示]

  1. 1.SignalRとは
  2. 2.構築の下準備
  3. 3.コーディング
  4. 4.動かしてみる
  5. 5.おまけ


SignalRとは


簡単に言うと、ウェブサーバーとリアルタイムにやり取りするための仕組みをまとめたライブラリーです。

通常のウェブサーバーはリクエストに対して応える(レスポンス)という形式になっています。そのためクライアント側が常に能動的にサーバーに最新情報を問合せる必要があります。頻繁に更新されるデータであれば、いつもクライアントがサーバー側に最新状態のデータを取りに行く必要があり、サーバー側からしたら勘弁してくれよ・・という感じです。

そこで、SignalRではサーバー側からクライアント側に情報をプッシュすることによって無駄なリクエストを削減し、リアルタイムな体験を演出していきます。


構築の下準備


まずはベースとなるプロジェクトを新しく作成します。ASP.NET Core Web アプリケーションを選択します。


次は、.NET Core x ASP.NET Core 2.1を選択し、Web アプリケーション(モデルビューコントローラー)を選択します。



次に、.NET Core x ASP.NET Core 2.1を選択して、WebApplicationSignalRDemo1を選択します。



コントローラー、モデル、ビューなどが自動生成されます。NuGetの中にコアのライブラリーであるMicrosoft.AspNetCore.Appがあることを確認します。



Microsoft.AspNetCore.Appの中にはすでに、Microsoft.AspNetCore.SignalRライブラリーが内包されていますので、とくにNuGetなどで個別にライブラリーを管理する必要はありません。

ただ、クライアント側で利用するJavascriptは必要になりますので、パッケージマネージャーコンソールから下記のコマンドを使って入手します。 npmは事前にインストールされている必要があります。(こちらよりインストール: https://nodejs.org/en/

npm init -y
npm install @aspnet/signalr



ダウンロードしたjsファイルは /wwwroot/lib/sinalr/signalr.js に格納します。



コーディング


さて、下準備が終わったところでコードを書いていきます。 まずはクライアント側とサーバー側のパイプとなるハブクラスを作ります。 プロジェクト傘下にHubsというフォルダーを作成し、その中にChatHub.csというクラスを作成します。


using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;

namespace WebApplicationSignalRDemo1.Hubs
{
    /// This is a hub class
    public class ChatHub : Hub
    {
        /// handle sending messages
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

次に、プロジェクトがSignalRを使うように設定をします。 Startup.ConfigureServices メソッドを編集です。ここにあるservices.AddSignalRでDIにて使えるようにします。


using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WebApplicationSignalRDemo1.Hubs;

namespace WebApplicationSignalRDemo1
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });


            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            // Add SignalR
            services.AddSignalR();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();
            app.UseCors("CorsPolicy");

            // Route to hub
            app.UseSignalR(routes =>
            {
                routes.MapHub("/chatHub");
            });

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}



あと少しで完成です。次はクライアント側のJavascript。wwwroot/js フォルダーの中に新たに chat.js を作成します。



"use strict";

var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

connection.on("ReceiveMessage", function (user, message) {
    var msg = message.replace(/&/g, "&").replace(//g, ">");
    var encodedMsg = user + " の発言: " + msg;
    var li = document.createElement("li");
    li.textContent = encodedMsg;
    document.getElementById("messagesList").appendChild(li);
});

connection.start().catch(function (err) {
    return console.error(err.toString());
});

document.getElementById("sendButton").addEventListener("click", function (event) {
    var user = document.getElementById("userInput").value;
    var message = document.getElementById("messageInput").value;
    connection.invoke("SendMessage", user, message).catch(function (err) {
        return console.error(err.toString());
    });
    event.preventDefault();
});


最後にビューを作成します。 /Views/Home/Index.cshtml を作成します。



@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>リアルタイムチャット</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B" crossorigin="anonymous">
</head>
<body>
    <div class="container py-5">
        <div class="row">
            <div class="col-sm-6 mb-3">
                <!--Input-->
                <div class="form-group">
                    <label for="messageInput">メッセージ</label>
                    <input type="text" id="messageInput" class="form-control" placeholder="メッセージをここに入力にしてください">
                </div>
                <div class="form-group">
                    <label for="userInput">名前</label>
                    <input type="text" class="form-control" id="userInput" placeholder="あなたのお名前を入力してください">
                </div>
                <button type="button" id="sendButton" class="btn btn-primary">送信</button>
            </div>
            <div class="col-sm-6 mb-3">
                <!--Output-->
                <ul id="messagesList"></ul>
            </div>
        </div>
    </div>
    <script src="~/lib/signalr/signalr.js"></script>
    <script src="~/js/site.js"></script>
    <script src="~/js/chat.js"></script>
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js" integrity="sha384-o+RDsa0aLu++PJvFqy8fFScvbHFLtbvScb8AjopnFD+iEQ7wo/CG0xlczd+2O/em" crossorigin="anonymous"></script>
</body>
</html>


動かしてみる


早速動かしてみます。EdgeとChrome2つのブラザーを開き、ローカル環境である https://localhost:44340/ と入力し、片方のブラザーでメッセージを入力してみます。左のブラウザーで送信ボタンを押したと同時に右のブラザーでも反映されました。



このライブラリーを使った応用技術はたくさんありますので、色々取組んでみてください。 今回作成したサンプルコードをこちらで公開しておきます。

https://github.com/TRANSCOSMOSRND/SignalR-Demo1-ASP.NET-Core-2.1/


おまけ


せっかく作ったので、ライブ環境でも使えるようにリリースしてみましょう。プロジェクトを右クリックし、発行ボタンをクリックします。


新規作成を選択して、右下の発行をクリック。



新しいウェブアプリケーションサーバーを選択して作成をおえたら完了! こちらでライブ環境を利用できます。 




ECXサイト編集部
ECXサイト編集部
トランスコスモスのECX本部が運営するサービスサイト「ECX」編集部です。コーディング、WEBデザイン、SEM、UI改善などの実務経験豊富なメンバーで執筆・運営・管理をしております。

Shopify(ショッピファイ)ストア構築・制作、
運用代行について問い合わせ

Shopifyアプリ解説・紹介記事

ShopifyのECサイト制作ならトランスコスモス

トランスコスモスは、Shopifyのエンタープライズ版「Shopify Plus」の優れた成果を持つ提携企業として認定された、国内に7社しかいない(2021年9月時点)最上位の公式パートナーです。

Shopifyを使ったECサイト制作から、調査分析・戦略立案、WEB広告(SEM)、ECサイト制作、お客様サポート、受発注、フルフィルメントまで業務設計・運用代行いたします。

トランスコスモスのEC全領域を網羅するサービス

関連記事


【無料】セミナー動画視聴


EC関連サービス


数字で見るトランスコスモスの強み

お気軽に
お問い合わせください

Shopify(ショッピファイ)
ECストア構築・運用代行

トランスコスモスは日本最上位の「Shopifyプラスパートナー」企業です
ロジスティクスサービス

 記事カテゴリー

【週間ランキング】ECブログ人気記事

ロジスティクス関連 新着記事

【初心者必見!】Shopifyマニュアル

 Tag(タグ)一覧

正社員募集(求人)

 【無料】資料ダウンロード

Shopify認定パートナー企業

shopify plus partner
トランスコスモスは最上位の「Shopify Plus partner(ショッピファイプラスパートナー)」です。
Shopifyでのサイト制作ならお任せください!
ECソリューションをお届けするサービスサイト

トランスコスモス株式会社
CX事業統括
ECX本部

〒150-0011
東京都渋谷区東1-2-20
渋谷ファーストタワー
050-1751-7700(代表)

経済産業省が定める「DX認定事業者」
トランスコスモスは経済産業省が定める「DX認定事業者」
トランスプラス
トランスコスモスの全社的な情報を発信するオウンドメディア
cotra
コンタクト/コールセンターに携わる方への情報サイト
shopify構築・制作・運用