🐳简介
SignalR是一个用于ASP.NET的库,它允许服务器代码向连接的客户端实时发送推送通知。它使用WebSockets作为底层传输机制,但如果浏览器不支持WebSockets,它会自动回退到其他兼容的技术,如服务器发送事件(Server-Sent Events)或长轮询。
SignalR的主要特点是它支持双向通信,这意味着服务器可以主动向客户端发送消息,而客户端也可以发送消息给服务器。这与传统的HTTP请求不同,后者通常是单向的,即客户端向服务器发送请求,然后等待响应。
SignalR的使用场景包括:
-
聊天应用:SignalR可以用来构建实时聊天应用,用户可以即时接收和发送消息。
-
实时数据更新:例如股票交易平台,可以使用SignalR实时更新股票价格和交易信息。
-
协作工具:多用户编辑同一文档或共享白板时,可以使用SignalR来同步不同用户的操作。
-
游戏:多人在线游戏可以使用SignalR来同步玩家的动作和游戏状态。
-
实时通知:网站可以使用SignalR来推送通知给用户,例如新消息提醒或系统更新通知。
-
物联网(IoT):可以使用SignalR来实时监控和控制连接的设备。
🐳案例演示
首先,创建一个asp.net core web api
👻定义通讯中心类
定义一个名为 ChatHub
的 SignalR 通讯中心类,继承 Hub
类。
-
SendMsg
方法:这是一个自定义方法,它可以被前端客户端通过 SignalR 连接调用,当客户端调用此方法时,它会接收一个用户ID (userId
) 和一条消息 (msg
),然后将格式化后的消息发送给连接的客户端。如下代码,使用All则是发送给所有客户端,使用Others则是发送给除自己以外的所有客户端。 -
OnConnectedAsync
方法:重写方法,当客户端成功连接到ChatHub
时,会触发此方法。在这个示例中,方法体为空,但可以在这里添加连接时需要执行的逻辑。 -
OnDisconnectedAsync
方法:重写方法,当客户端断开与ChatHub
的连接时,会触发此方法。同样,方法体为空,但可以在这里添加断开连接时需要执行的逻辑。
public class ChatHub : Hub
{
public async Task SendMsg(long userId, string msg)
{
string sendMsg = $"服务的收到你的消息,user={userId},msg={msg}";
//服务端推送给所有客户端
await Clients.All.SendAsync("ReceiveMsg", sendMsg);
//服务端推送给 除自已以外 的所有客户端
await Clients.Others.SendAsync("ReceiveMsg", sendMsg);
}
//客户端成功连接时,会触发此方法
public override Task OnConnectedAsync()
{
return Task.CompletedTask;
}
//客户端断开连接时,会触发此方法
public override Task OnDisconnectedAsync(Exception? exception)
{
return Task.CompletedTask;
}
}
👻添加SignalR服务与配置跨域
打开Program,如下代码中四处注释处添加代码
using SignalRServer.Hubs;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
//添加SignalR服务
builder.Services.AddSignalR();
//配置跨域
builder.Services.AddCors(opt =>
{
opt.AddPolicy("WS.Client", p =>
{
p.AllowCredentials();
p.AllowAnyHeader();
p.AllowAnyMethod();
p.SetIsOriginAllowed(s => true); //允许任何客户
//指定跨域
// p.WithHeaders();
});
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
//在处理管道中启用策略
app.UseCors("WS.Client");
app.UseAuthorization();
app.MapControllers();
//映射通讯中心的请求路径
app.MapHub<ChatHub>("/Hubs");
app.Run();
然后就可以启动我们的项目了!
👻客户端
写两个html来测试一下
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>通讯1</title>
</head>
<body>
<input type="button" value="发送" id="btnSend">
</body>
</html>
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<script src="node_modules/@microsoft/signalr/dist/browser/signalr.min.js"></script>
<script>
var connection = new signalR.HubConnectionBuilder()
.withUrl("http://localhost:5039/Hubs")
.build();
//当连接成功的时候
connection.start().then(function (){
console.log("客户端连接成功")
})
//接受服务端主动推送过来的消息
connection.on("ReceiveMsg",function(msg){
alert(msg);
})
$('#btnSend').click(function(){
connection.invoke("SendMsg",1,"测试1").catch(function(err){
console.log(err);
});
})
</script>
第二个html只用在connection.invoke()时把参数换一下就好了,打开两个HTML,控制台看一下输出,连接成功
通讯1的网页中点一下发送,再切换到通讯2网页,收到了服务器发来的消息
🐤此案例已上传到gitee中,案例地址👇
SignalR案例 (gitee.com)https://gitee.com/libihao520/signalR-case-study