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。

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

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

相关推荐
正在走向自律几秒前
时序数据管理:金仓数据库破局之道
java·后端·struts·时序数据库·金仓kes v9
moxiaoran57536 分钟前
springboot多模块项目构建docker镜像
spring boot·后端·docker
小北方城市网8 分钟前
SpringBoot 集成消息队列实战(RabbitMQ/Kafka):异步通信与解耦,落地高可靠消息传递
java·spring boot·后端·python·kafka·rabbitmq·java-rabbitmq
JaguarJack14 分钟前
PHP 8.5 闭包和一等可调用对象进入常量表达式
后端·php·服务端
冷冷的菜哥18 分钟前
go(golang)调用ffmpeg对视频进行截图、截取、增加水印
后端·golang·ffmpeg·go·音视频·水印截取截图
短剑重铸之日20 分钟前
《7天学会Redis》特别篇:Redis十大经典面试题2
数据库·redis·后端·缓存·架构
草莓熊Lotso26 分钟前
Qt 控件核心入门:从基础认知到核心属性实战(含资源管理)
运维·开发语言·c++·人工智能·后端·qt·架构
赴前尘9 小时前
golang 查看指定版本库所依赖库的版本
开发语言·后端·golang
Marktowin15 小时前
Mybatis-Plus更新操作时的一个坑
java·后端