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

相关推荐
魔尔助理顾问2 小时前
一个简洁高效的Flask用户管理示例
后端·python·flask
李长渊哦6 小时前
使用Druid连接池优化Spring Boot应用中的数据库连接
数据库·spring boot·后端
web135085886356 小时前
【Spring Boot】Spring AOP动态代理,以及静态代理
spring boot·后端·spring
nbsaas-boot7 小时前
Go 自动升级依赖版本
开发语言·后端·golang
zzyh1234567 小时前
springcloud的组件及作用
后端·spring·spring cloud
尚学教辅学习资料8 小时前
基于SpringBoot的图书借阅小程序+LW参考示例
spring boot·后端·小程序·java毕设·图书借阅
山海不说话8 小时前
从零搭建微服务项目Base(第5章——SpringBoot项目LogBack日志配置+Feign使用)
spring boot·后端·spring·spring cloud·微服务·logback
databook9 小时前
『Python底层原理』--CPython的变量实现机制
后端·python
初尘屿风9 小时前
小程序类毕业设计选题题目推荐 (29)
spring boot·后端·学习·微信·小程序·课程设计