ASP.NET Core SignalR 入门

一、简介

📢 SignalR的主要功能是提供服务器和客户端之间的实时通信。当连接的客户端变得可用时,服务器可以立即向其推送内容,而不是等待客户端发起请求。这种功能特别适合需要实时更新数据的应用场景,如聊天应用、实时数据分析、多人协作编辑工具等‌。

二、起步

🎯本文主要介绍使用 SignalR 生成实时应用的基础知识。

  • 创建 Web 项目。
  • 添加 SignalR 客户端库。
  • 创建 SignalR 中心。
  • 配置项目以使用 SignalR。
  • 添加可将消息从任何客户端发送到所有连接客户端的代码。

🪁具体介绍请移步:ASP.NET Core SignalR 双工通信-CSDN博客

2.1 开发工具选择

这里使用 Visual Studio 2022 🛠️

2.2 创建 Web 应用项目

启动 Visual Studio 2022 并选择"创建新项目"。

在"创建新项目"对话框中选择"ASP.NET Core Web 应用(Razor 页面)",然后选择"下一步"。

在"配置新项目"对话框中,为"项目名称"输入 SignalRChat。 请务必将项目命名为 SignalRChat(包括匹配大写),以便命名空间与教程中的代码匹配。

选择下一步

在"其他信息"对话框中,选择 ".NET 8.0 (长期支持)" ,然后选择"创建"。

三、添加 SignalR 客户端库

ASP.NET Core 共享框架中包含 SignalR 服务器库。 JavaScript 客户端库不会自动包含在项目中。 对于此教程,使用库管理器 (LibMan) 从 unpkg 获取客户端库。 unpkg 是一个快速的全局内容分发网络,适用于 npm 上的所有内容。

在 "解决方案资源管理器" >中,右键单击项目,然后选择 "添加" "客户端库" 。

在"添加客户端库"对话框中:

  • 为"提供程序"选择 "unpkg"
  • 对于"库",请输入 @microsoft/signalr@latest
  • 选择 "选择特定文件" ,展开 "dist/browser" 文件夹,然后选择 signalr.js 和 signalr.min.js。
  • 将"目标位置"设置为 wwwroot/js/signalr/。
  • 选择"安装" 。

LibMan 创建 wwwroot/js/signalr 文件夹并将所选文件复制到该文件夹。

四、创建 SignalR 中心

中心是一个类,用作处理客户端 - 服务器通信的高级管道。

在 SignalRChat 项目文件夹中,创建 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,以向所有客户端发送消息。 本教程后面部分将显示调用该方法的 JavaScript 客户端代码。 SignalR 代码是异步模式,可提供最大的可伸缩性。

五、配置 SignalR

必须将 SignalR 服务器配置为将 SignalR 请求传递给 SignalR。 将以下突出显示的代码添加到 Program.cs 文件。

cs 复制代码
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();

以上突出显示的代码将 SignalR 添加到 ASP.NET Core 依赖关系注入和路由系统。

六、添加 SignalR 客户端代码

使用以下代码替换 Pages/Index.cshtml 中的内容:

cs 复制代码
@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>

前面的标记:

  • 创建文本框和提交按钮。
  • 使用 id="messagesList" 创建一个列表,用于显示从 SignalR 中心接收的消息。
  • 包含对 SignalR 的脚本引用,并在下一步中创建 chat.js 应用代码。

在 wwwroot/js 文件夹中,使用以下代码创建 chat.js 文件:

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:

  • 创建并启动连接。
  • 向"提交"按钮添加一个用于向中心发送消息的处理程序。
  • 向连接对象添加一个用于从中心接收消息并将其添加到列表的处理程序。

从地址栏复制 URL,打开另一个浏览器实例或选项卡,并在地址栏中粘贴该 URL。

选择任一浏览器,输入名称和消息,然后选择"发送消息"按钮。

两个页面上立即显示名称和消息。

相关推荐
陈随易19 分钟前
前端大咖mizchi不满Rust、TypeScript却爱上MoonBit
前端·后端·程序员
雨中飘荡的记忆2 小时前
Multi-Agent + Skills + Spring AI 构建自主决策智能体
后端·spring
我叫黑大帅2 小时前
Go 语言并发编程的 “工具箱”
后端·面试·go
用户8356290780513 小时前
Python 实现 PowerPoint 形状动画设置
后端·python
用户908324602733 小时前
Spring Boot 缓存架构:一行配置切换 Caffeine 与 Redis,透明支持多租户隔离
后端
tyung3 小时前
zhenyi-base 开源 | Go 高性能基础库:TCP 77万 QPS,无锁队列 16ns/op
后端·go
子兮曰4 小时前
Humanizer-zh 实战:把 AI 初稿改成“能发布”的技术文章
前端·javascript·后端
桦说编程4 小时前
你的函数什么颜色?—— 深入理解异步编程的本质问题(上)
后端·性能优化·编程语言
百度地图汽车版4 小时前
【AI地图 Tech说】第九期:让智能体拥有记忆——打造千人千面的小度想想
前端·后端
臣妾没空4 小时前
Elpis 全栈框架:从构建到发布的完整实践总结
前端·后端