使用 SignalR 实现 ASP.NET Core 实时消息系统
阅读:144
点赞:0
一. SignalR 简介
SignalR 是微软为 ASP.NET 开发的一个库,简化了为应用程序添加实时 web 功能的过程。通过 SignalR,服务器可以在新数据可用时立即将内容推送到已连接的客户端,而无需等待客户端发出数据请求。
二. 创建项目并配置 SignalR
1. 新建 ASP.NET Core 项目
在 Visual Studio 中创建一个新的 ASP.NET Core 项目。本文使用的是 Visual Studio 2022 社区版,项目模板根据需求选择。将项目命名为 "SignalR"。
在 Index 操作中添加了一个简单的随机数逻辑,只是为了区分聊天的不同用户。
using Microsoft.AspNetCore.Mvc;
using SignalR.Models;
using System.Diagnostics;
namespace SignalR.Controllers
{
public class HomeController : Controller
{
// 日志对象注入
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
// Index 方法,展示首页并生成随机用户名
public IActionResult Index()
{
// 随机生成一个用户ID
Random random = new();
ViewBag.User = "User " + random.Next(100);
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
代码解释:
-
使用 Random
类生成随机数,模拟不同用户的标识。 -
ILogger
用于日志记录。
2. 添加 SignalR CDN 和前端界面
在视图文件中添加 SignalR 的 CDN 脚本路径,同时设计一个简单的聊天界面。
<!-- 引入 SignalR JavaScript 库 -->
<script src="https://unpkg.com/@microsoft/signalr@latest/dist/browser/signalr.min.js" type="text/javascript"></script>
<div class="text-center">
<!-- 显示欢迎信息和用户名 -->
<h1 class="display-4">欢迎进入聊天: @ViewBag.User</h1>
<!-- 输入消息框 -->
<input type="text" id="txtMessage" />
<!-- 发送消息按钮 -->
<input type="submit" id="btnSendMessage" value="发送" title="发送消息" />
<!-- 隐藏的用户名输入框 -->
<input type="hidden" id="hdnUserName" value="@ViewBag.User" />
<div class="chat"></div>
</div>
代码解释:
-
signalr.min.js
是 SignalR 的客户端库。 -
输入框用于发送消息, ViewBag.User
显示当前用户。
三. 实现 SignalR Hub
1. 创建 ChatHub 类
创建一个基本的 SignalR Hub 类,负责所有客户端的连接和消息分发。
现在在包管理器控制台中使用以下命令安装 Microsoft SignalR nuget 包。
using Microsoft.AspNetCore.SignalR;
namespace SignalR
{
// 定义 SignalR Hub 类
public class ChatHub : Hub
{
// 向所有连接的客户端发送消息
public async Task SendMessage(string user, string message, string date)
{
// 发送接收到的消息到所有客户端
await Clients.All.SendAsync("ReceiveMessage", user, message, date);
}
}
}
代码解释:
-
ChatHub
是一个继承自Hub
的类,用于处理 SignalR 连接。 -
SendMessage
方法通过Clients.All.SendAsync
发送消息到所有客户端。
2. 注册 SignalR 服务
在 Program.cs
中,注册 SignalR 并映射 ChatHub
路径。
var builder = WebApplication.CreateBuilder(args);
// 注册 SignalR 服务
builder.Services.AddSignalR();
var app = builder.Build();
// 映射 SignalR Hub 到 /chathub 路径
app.MapHub<ChatHub>("/chathub");
代码解释:
-
AddSignalR
方法添加了 SignalR 服务。 -
MapHub<ChatHub>
方法映射了 Hub 的路径,使其在/chathub
路径下处理请求。
四. 实现客户端 SignalR 逻辑
使用 jQuery 编写客户端的 SignalR 连接逻辑,发送和接收消息。
// 创建 SignalR 连接
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub", {
skipNegotiation: true,
transport: signalR.HttpTransportType.WebSockets
})
.build();
// 监听 "ReceiveMessage" 事件,接收服务器发送的消息
connection.on("ReceiveMessage", (user, message, date) => {
// 生成消息内容并显示到页面
let h = `<br/><span class="user-chat">${user} : [${date}] ${message}</span>`;
$('.chat').append(h);
});
// 启动 SignalR 连接
connection.start().catch(err => {
console.log(err.toString());
});
// 发送消息事件
$(document).on("click", "#btnSendMessage", function (e) {
e.preventDefault(); // 阻止默认行为
var user = $("#hdnUserName").val(); // 获取当前用户
var message = $("#txtMessage").val(); // 获取输入的消息
var date = new Date(); // 获取当前时间
if (message.trim() !== '') {
// 调用服务器的 SendMessage 方法
connection.invoke("SendMessage", user, message, date)
.catch(function (err) {
console.error(err.toString());
});
}
});
代码解释:
-
使用 signalR.HubConnectionBuilder
创建 SignalR 连接。 -
connection.on("ReceiveMessage")
用于接收服务器发送的消息并将其展示在页面上。 -
connection.invoke("SendMessage")
向服务器发送消息。
五. 总结
通过本文,您学习了如何使用 ASP.NET Core 和 SignalR 库来实现一个简单的实时聊天应用。SignalR 提供了强大的功能,使得服务器可以即时向客户端推送更新,适用于聊天、通知等场景。