Nguon: Microsoft Learn · .NET 8.0

Bắt đầu với ASP.NET Core SignalR

Nguồn: Get started with ASP.NET Core SignalR

Hướng dẫn này dạy những kiến thức cơ bản về việc xây dựng ứng dụng thời gian thực (real-time) bằng cách sử dụng SignalR. Bạn sẽ học cách:

Kết thúc hướng dẫn, bạn sẽ có một ứng dụng chat (trò chuyện) hoạt động được.

Điều kiện tiên quyết (Prerequisites)

Visual Studio:

Visual Studio Code:

Tạo dự án ứng dụng web

Visual Studio:

Khởi động Visual Studio 2022 và chọn Create a new project.

Trong dialog Create a new project, chọn ASP.NET Core Web App (Razor Pages), sau đó chọn Next.

Trong dialog Configure your new project, nhập SignalRChat cho Project name. Quan trọng là phải đặt tên dự án là SignalRChat, bao gồm khớp chữ hoa/thường, để namespace khớp với code trong hướng dẫn.

Chọn Next.

Trong dialog Additional information, chọn .NET 8.0 (Long Term Support) rồi chọn Create.

Visual Studio Code:

Hướng dẫn này giả định quen thuộc với VS Code.

dotnetcli
dotnet new webapp -o SignalRChat
code -r SignalRChat

Lệnh dotnet new tạo một dự án Razor Pages mới trong thư mục SignalRChat.

Lệnh code mở thư mục SignalRChat trong phiên Visual Studio Code hiện tại.

Visual Studio Code có thể hiển thị hộp thoại hỏi: Do you trust the authors of the files in this folder?

Thêm thư viện client SignalR

Thư viện server SignalR được bao gồm trong ASP.NET Core shared framework. Thư viện JavaScript client không được tự động bao gồm trong dự án. Trong hướng dẫn này, hãy sử dụng Library Manager (LibMan) để lấy thư viện client từ unpkg. unpkg là một mạng phân phối nội dung (CDN) toàn cầu nhanh chóng cho mọi thứ trên npm.

Visual Studio:

Trong Solution Explorer, nhấp chuột phải vào dự án và chọn Add > Client-Side Library.

Trong dialog Add Client-Side Library:

LibMan tạo thư mục wwwroot/js/signalr và sao chép các file đã chọn vào đó.

Visual Studio Code:

Trong integrated terminal, chạy các lệnh sau để cài đặt LibMan sau khi gỡ cài đặt phiên bản trước nếu có:

dotnetcli
dotnet tool uninstall -g Microsoft.Web.LibraryManager.Cli
dotnet tool install -g Microsoft.Web.LibraryManager.Cli

Chạy lệnh sau để lấy thư viện client SignalR bằng LibMan:

console
libman install @microsoft/signalr@latest -p unpkg -d wwwroot/js/signalr --files dist/browser/signalr.js

Các tham số chỉ định các tùy chọn sau:

Đầu ra trông tương tự như sau:

console
Downloading file https://unpkg.com/@microsoft/signalr@latest/dist/browser/signalr.js...
wwwroot/js/signalr/dist/browser/signalr.js written to disk
Installed library "@microsoft/signalr@latest" to "wwwroot/js/signalr"

Tạo SignalR hub

Một hub (trung tâm kết nối) là một lớp đóng vai trò làm pipeline (đường ống xử lý) cấp cao xử lý giao tiếp client-server.

Trong thư mục dự án SignalRChat, tạo thư mục Hubs.

Trong thư mục Hubs, tạo lớp ChatHub với code sau:

csharp
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);
        }
    }
}

Lớp ChatHub kế thừa từ lớp SignalR Hub. Lớp Hub quản lý các kết nối, nhóm và tin nhắn.

Phương thức SendMessage có thể được gọi bởi một client đã kết nối để gửi tin nhắn đến tất cả các client. Code JavaScript client gọi phương thức này được hiển thị sau trong hướng dẫn. Code SignalR là bất đồng bộ (asynchronous) để cung cấp khả năng mở rộng tối đa.

Cấu hình SignalR

Server SignalR phải được cấu hình để chuyển các yêu cầu SignalR đến SignalR. Thêm code được làm nổi bật sau vào file Program.cs:

csharp
using SignalRChat.Hubs;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
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();

Code được làm nổi bật ở trên thêm SignalR vào hệ thống dependency injection (tiêm phụ thuộc) và routing (định tuyến) của ASP.NET Core.

Thêm code client SignalR

Thay thế nội dung trong Pages/Index.cshtml bằng code sau:

cshtml
@page
<div class="container">
    <div class="row p-1">
        <div class="col-1">User</div>
        <div class="col-5"><input type="text" id="userInput" /></div>
    </div>
    <div class="row p-1">
        <div class="col-1">Message</div>
        <div class="col-5"><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>
<script src="~/js/signalr/dist/browser/signalr.js"></script>
<script src="~/js/chat.js"></script>

Markup trên:

Trong thư mục wwwroot/js, tạo file chat.js với code sau:

javascript
"use strict";

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

//Disable the send button until connection is established.
document.getElementById("sendButton").disabled = true;

connection.on("ReceiveMessage", function (user, message) {
    var li = document.createElement("li");
    document.getElementById("messagesList").appendChild(li);
    // We can assign user-supplied strings to an element's textContent because it
    // is not interpreted as markup. If you're assigning in any other way, you 
    // should be aware of possible script injection concerns.
    li.textContent = `${user} says ${message}`;
});

connection.start().then(function () {
    document.getElementById("sendButton").disabled = false;
}).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();
});

JavaScript trên:

Chạy ứng dụng

Chọn Ctrl+F5 để chạy ứng dụng mà không cần debug.

Sao chép URL từ thanh địa chỉ, mở một phiên trình duyệt hoặc tab khác, và dán URL vào thanh địa chỉ.

Chọn một trong hai trình duyệt, nhập tên và tin nhắn, và chọn nút Send Message.

Tên và tin nhắn được hiển thị ngay lập tức trên cả hai trang.

Mẹo: Nếu ứng dụng không hoạt động, hãy mở công cụ developer của trình duyệt (F12) và đi đến console. Tìm các lỗi có thể liên quan đến code HTML và JavaScript. Ví dụ, nếu signalr.js được đặt trong một thư mục khác với hướng dẫn, tham chiếu đến file đó sẽ không hoạt động dẫn đến lỗi 404 trong console.

Nếu xảy ra lỗi ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY trong Chrome, hãy chạy các lệnh sau để cập nhật chứng chỉ phát triển:

``dotnetcli dotnet dev-certs https --clean dotnet dev-certs https --trust ``

Xuất bản lên Azure

Để biết thông tin về việc triển khai lên Azure, xem Quickstart: Deploy an ASP.NET web app. Để biết thêm thông tin về Azure SignalR Service, xem What is Azure SignalR Service?.