こんにちは、近ため管理人です。ASP.NET Core MVCを使用したアプリケーションにWebSocketを活用したチャット機能を実装する際に、SignalRというライブラリに出会いました。以下の公式チュートリアルもありますが、Razor Pagesで書かれており、MVCでのチュートリアルはありません。

よって、今回はこちらのチュートリアルをASP.NET Core MVC(Model-View-Controller)で実装した場合のケースで書き直してみようと思います。
目次
開発環境
- Windows10またはWindows11
- Visual Studio 2022
- .NET 8
事前準備として、Visual Studio Installerに「ASP.NETとWeb開発」が追加されていない方はインストールしてください。
チュートリアルでやることと成果物のイメージ
ここでは以下のステップでチュートリアルを進めていきます。
- ASP.NET Core MVCプロジェクトの作成
- SignalRクライアントライブラリの追加
- SignalRハブの作成
- SignalRを使用する際のプロジェクト設定
- クライアント側のチャットコードの追加
成果物となるチャットアプリは以下のような感じです。
- ユーザー認証などの機能はありません。
- ユーザー名、メッセージ内容はクライアントが入力します。
- URLにアクセスしたクライアント全員にメッセージがリアルタイムで送信されます。
それでははじめましょう!
ASP.NET Core MVCプロジェクトの作成
Visual Studio 2022 を開始し、 [新しいプロジェクトの作成] を選択します。
[新しいプロジェクトの作成] ダイアログで、[ASP.NET Core Web アプリ (Model-View-Controller)、[次へ] の順に選択します。
[新しいプロジェクトの構成] ダイアログで、 [プロジェクト名] に「SignalRChat
」と入力します。 名称を一致させておくとコピペしやすいです。
[次へ] を選択します。
[追加情報] ダイアログで、[.NET 8.0 (長期的なサポート)] を選択し、[作成] を選択します。
SignalRクライアントライブラリの追加
SignalRはサーバー側とクライアント側の両方にライブラリがあります。サーバー側はASP.NET Core MVCなので、共有フレームワークに含まれています。一方でクライアント側、今回はJavaScript側のライブラリは手動で追加する必要があります。
ライブラリマネージャーのLibManを使用してunpkgからSignalRライブラリを取得します。
ソリューション エクスプローラーで、プロジェクトを右クリックし、[追加]>[クライアント側のライブラリ] を選択します。
- [プロバイダー] で [unpkg] を選択します。
- [ライブラリ] に、「
@microsoft/signalr@latest
」と入力します。 - [Choose specific files](特定のファイルの選択) を選択して dist/browser フォルダーを展開し、
signalr.js
とsignalr.min.js
を選択します。 - [ターゲットの場所] を
wwwroot/js/signalr/
に設定します。 - [インストール] を選択します。
LibMan によって
wwwroot/js/signalr
フォルダーが作成され、ライブラリが追加されます。
SignalRハブの作成
SignalRにおけるハブの役割はクライアントとサーバー間のリアルタイム通信を管理することです。
チュートリアルではプロジェクト直下にHubsフォルダを作成します。その後、Hubsフォルダを右クリック、追加>クラスからChatHub.csクラスを作成します。
using Microsoft.AspNetCore.SignalR;
namespace SignalRChat.Hubs {
public class ChatHub : Hub {
public async Task SendMessage(string user, string message) {
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
}
ChatHub
クラスは、SignalRHub クラスを継承します。 Hub
クラスでは、以下を行えます。
- 接続管理
…クライアントの接続や切断を管理し、必要に応じて特定の処理を実行します。 - メソッドの定義
…クライアントが呼び出すことができるメソッドを定義し、サーバー上の特定の処理を実行できます。 - メッセージ送信
…クライアントから送信されたメッセージを他の全ての接続されたクライアントに配信できます。 - グループ管理
…クライアントをグループに分けて、特定のグループにのみメッセージを送信できます。
SendMessage
メソッドは、メッセージをすべてのクライアントに送信するために、接続されたクライアントによって呼び出されます。後ほどクライアント側からこのメソッドを呼び出す処理を実装します。
SignalRを使用する際のプロジェクト設定
先ほど、SignalRはデフォルトでASP.NET Core MVCの共有フレームワークに含まれていると書きましたが、実際に使用するためには Program.cs をいくつか設定する必要があります。
using SignalRChat.Hubs; //追加
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddSignalR(); //追加
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.MapHub<ChatHub>("/chathub"); //追加
app.Run();
これでASP.NET Core MVCプロジェクトでSignalRが使えるようになりました。
クライアント側のチャットコードの追加
Views/Home/Index.cshtml
の内容を次のコードに置き換えます。
@{
ViewData["Title"] = "Home Page";
}
<div class="container">
<div class="row p-1">
<div class="col-2">User</div>
<div class="col-4"><input type="text" class="w-100" id="userInput" /></div>
</div>
<div class="row p-1">
<div class="col-2">Message</div>
<div class="col-4"><input type="text" class="w-100" id="messageInput" /></div>
</div>
<div class="row p-1">
<div class="col-6 text-end">
<input type="button" id="sendButton" value="Send Message" />
</div>
</div>
<div class="row p-1">
<div class="col-6">
<hr />
</div>
</div>
<div class="row p-1">
<div class="col-6">
<ul id="messagesList"></ul>
</div>
</div>
</div>
@section Scripts {
<script src="~/js/signalr/signalr.js"></script>
<script src="~/js/chat.js"></script>
}
ここでは、テキスト ボックスと送信ボタンを作成します。SignalR ハブから受信したメッセージを表示するために、id="messagesList"
を使用してリストを作成します。SignalR へのスクリプト参照と、次の手順で作成する chat.js
を参照しています。
では、wwwroot/js
フォルダー内に、次のコードを使用して chat.js
ファイルを作成します。
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.build();
document.getElementById("sendButton").disabled = true;
connection.on("ReceiveMessage", (user, message) => {
const li = document.createElement("li");
document.getElementById("messagesList").appendChild(li);
li.textContent = `${user}: ${message}`;
});
connection.start()
.then(() => document.getElementById("sendButton").disabled = false)
.catch(err => console.error(err.toString()));
document.getElementById("sendButton").addEventListener("click", event => {
const user = document.getElementById("userInput").value;
const message = document.getElementById("messageInput").value;
connection.invoke("SendMessage", user, message).catch(err => console.error(err.toString()));
event.preventDefault();
});
以上です。
アプリを実行する
アプリを実行します。複数のブラウザを立ち上げて、URLをコピーします。今回はChromeとEdgeを開いてみました。
Chrome側でメッセージを送信すると、Edgeにも反映されました!
以上でアプリが正しく完成しました。このチュートリアルを更にカスタマイズして特定のグループでチャットしたり、1対1のプライベートチャットルームを作ったりしたいですね。
ここまでお読みいただきありがとうございました。ASP.NET Core MVCのチュートリアルを分かりやすくした記事も公開しているので、よかったらご活用ください。

コメント