构建实时应用程序在现代 Web 开发中变得至关重要,尤其是对于通知、聊天系统和实时更新等功能。SignalR 是一个强大的 ASP.NET 库,支持服务器端代码和客户端 Web 应用程序之间的无缝实时通信。
为什么使用 SignalR?
1、实时通信: 它支持实时更新,这对于现代动态应用程序(如聊天系统、游戏、实时体育更新和协作应用程序)至关重要。
2、自动重新连接: SignalR 在连接断开的情况下处理自动重新连接,确保实时通信的可靠性。
3、可扩展性: SignalR 是可缩放的,并且可以与其他服务(如 Azure SignalR 服务)结合使用,后者可处理横向扩展需求并提供高可用性。
4、跨平台: SignalR 支持多个平台,包括 .NET、JavaScript 和 Xamarin,从而在不同类型的应用程序中具有广泛的适用性。
5、简化开发: SignalR 提供了一个简单的 API,它抽象了实时通信的复杂性,使开发人员能够更轻松地实现这些功能。
创建 SignalR 服务端:
1、创建 ASP.Net Core Web API 项目
这里去掉“使用控制器”来构建最小 API 服务。
最后点击【创建】。
2、在项目中安装 SignalR 包
使用 NuGet 包管理器 UI 通过搜索“SignalR”,找到“Microsoft.AspNetCore.SignalR”安装
当然,也可以通过 NuGet 包管理器控制台来通过命令安装:
Install-Package Microsoft.AspNetCore.SignalR
3、在启动文件 Program.cs 中添加 SignalR 服务
builder.Services.AddSignalR();
4、创建 Hub 类 SignalRHub.cs
using Microsoft.AspNetCore.SignalR;
namespace SignalRApi
{
public class SignalRHub : Hub
{
///
/// 发布学生成绩
///
///学生姓名 ///得分 ///备注 /// public async Task SendMessage(string name, int score, string msg) { await Clients.All.SendAsync(“ReceiveScore”, name, score, msg); } public override async Task OnConnectedAsync() { string connectionId = Context.ConnectionId; await base.OnConnectedAsync(); } } }
5、创建后台服务持续推送消息类 WorkerService.cs
具体业务逻辑代码:
using Microsoft.AspNetCore.SignalR;
namespace SignalRApi
{
public class WorkerService : BackgroundService
{
private readonly IHubContext _signalRHub;
public WorkerService(IHubContext signalRHub)
{
_signalRHub = signalRHub;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
Console.WriteLine($"{DateTime.Now}:服务已启动");
Random rnd = new Random();
int score = rnd.Next(60, 100);
string[] students = { "段誉", "萧峰", "虚竹", "阿朱", "阿紫", "王语嫣", "木婉清", "钟灵", "阿碧", "慕容复", "段正淳", "鸠摩智" };
var name = students[rnd.Next(0, students.Length)];
await _signalRHub.Clients.All.SendAsync("ReceiveScore", name, score, $"{name}的成绩是{score}");
Console.WriteLine($"{DateTime.Now}:发布成绩:{name}获取{score}分");
await Task.Delay(4000, stoppingToken);
}
catch (Exception ex)
{
Console.WriteLine($"服务异常:{ex.Message}");
}
}
}
}
}
6、最后,需要在 Program.cs 中映射 SignalRHub 以及添加后台服务
builder.Services.AddHostedService();
app.MapHub("/hubs/score");
启动项目,查看效果:
SignalR 服务端搭建完毕,接下来,实现 SignalR 的客户端,用控制台程序实现。
创建 SignalR 客户端
1、创建控制台应用程序
同样的方法安装 SignalR 客户端包【Microsoft.AspNetCore.SignalR.Client】,
在 Program.cs 中添加代码:
using Microsoft.AspNetCore.SignalR.Client;
//here is SignalR Sender URL
string hubUrl = "http://localhost:5000/hubs/score";
var hubConnection = new HubConnectionBuilder().WithUrl(hubUrl).Build();
// Register a handler for messages from the SignalR hub
// "ReceiveStockPrice" is the topic to which SignalR sending the singnals
hubConnection.On<string, int, string>("ReceiveScore", (name, score, msg) =>
{
Console.WriteLine($"接收消息--> 学生:{name} 成绩:{score} 备注:{msg}");
});
try
{
// Start the connection
hubConnection.StartAsync().Wait();
Console.WriteLine("SignalR 已连接到服务器");
}
catch (Exception ex)
{
Console.WriteLine($"SignalR 连接服务异常:{ex.Message}");
throw;
}
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;
Console.CancelKeyPress += (sender, a) =>
{
a.Cancel = true;
Console.WriteLine("SignalR 停止连接");
cancellationTokenSource.Cancel();
};
try
{
await Task.Delay(Timeout.Infinite, cancellationToken);
}
catch (TaskCanceledException)
{
}
await hubConnection.StopAsync();
Console.WriteLine("SignalR 连接已关闭");
启动项目,查看效果: