ASP.NET Core 使用 SignalR 实现实时通讯

🐳简介

SignalR是一个用于ASP.NET的库,它允许服务器代码向连接的客户端实时发送推送通知。它使用WebSockets作为底层传输机制,但如果浏览器不支持WebSockets,它会自动回退到其他兼容的技术,如服务器发送事件(Server-Sent Events)或长轮询。

SignalR的主要特点是它支持双向通信,这意味着服务器可以主动向客户端发送消息,而客户端也可以发送消息给服务器。这与传统的HTTP请求不同,后者通常是单向的,即客户端向服务器发送请求,然后等待响应。

SignalR的使用场景包括:

  1. 聊天应用:SignalR可以用来构建实时聊天应用,用户可以即时接收和发送消息。

  2. 实时数据更新:例如股票交易平台,可以使用SignalR实时更新股票价格和交易信息。

  3. 协作工具:多用户编辑同一文档或共享白板时,可以使用SignalR来同步不同用户的操作。

  4. 游戏:多人在线游戏可以使用SignalR来同步玩家的动作和游戏状态。

  5. 实时通知:网站可以使用SignalR来推送通知给用户,例如新消息提醒或系统更新通知。

  6. 物联网(IoT):可以使用SignalR来实时监控和控制连接的设备。

🐳案例演示

首先,创建一个asp.net core web api

👻定义通讯中心类

定义一个名为 ChatHub 的 SignalR 通讯中心类,继承 Hub 类。

  1. SendMsg 方法:这是一个自定义方法,它可以被前端客户端通过 SignalR 连接调用,当客户端调用此方法时,它会接收一个用户ID (userId) 和一条消息 (msg),然后将格式化后的消息发送给连接的客户端。如下代码,使用All则是发送给所有客户端,使用Others则是发送给除自己以外的所有客户端。

  2. OnConnectedAsync 方法:重写方法,当客户端成功连接到 ChatHub 时,会触发此方法。在这个示例中,方法体为空,但可以在这里添加连接时需要执行的逻辑。

  3. OnDisconnectedAsync 方法:重写方法,当客户端断开与 ChatHub 的连接时,会触发此方法。同样,方法体为空,但可以在这里添加断开连接时需要执行的逻辑。

cs 复制代码
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,如下代码中四处注释处添加代码

cs 复制代码
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来测试一下

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

相关推荐
新知图书1 小时前
ASP.NET MVC添加视图示例
后端·asp.net·mvc
菠萝011 小时前
分布式不同数据的一致性模型
数据库·c++·分布式·后端
Code哈哈笑1 小时前
【基于SpringBoot的图书购买系统】操作Jedis对图书图书的增-删-改:从设计到实战的全栈开发指南
java·spring boot·后端·spring·交互·jedis
晴天_QingTian1 小时前
.NET8入门:14.ASP.NET Core MVC进阶——Model
asp.net·mvc·.net
hamish-wu2 小时前
spring boot 拦截器HandlerInterceptor 不生效的原因排查
java·spring boot·后端
薯条不要番茄酱2 小时前
【SpringBoot】零基础全面解析SpringBoot配置文件
java·spring boot·后端
lanbing8 小时前
非常适合初学者的Golang教程
开发语言·后端·golang
stormsha9 小时前
GO语言进阶:掌握进程OS操作与高效编码数据转换
开发语言·数据库·后端·golang·go语言·源代码管理
B1nna9 小时前
SpringBoot项目快速打包与部署,War包⽅式打包部署与Jar包⽅式打包部署两种方式
spring boot·后端·jar
声声codeGrandMaster12 小时前
Django实现文件上传
数据库·后端·python·django