.Net6使用SignalR实现前后端实时通信

代码部分

  • 后端代码 (Asp.net core web api,用的.net6)
  • Program.cs

代码运行逻辑:
​1. 通过 WebApplication.CreateBuilder(args) 创建一个 ASP.NET Core 应用程序建造器。
2. 使用 builder.Services.AddControllers() 添加 MVC 控制器服务和 builder.Services.AddSignalR() 添加 SignalR 服务。
3. 注册 Swagger 和 Cors 跨域设置的服务,并添加 ChatHub 类作为单例服务。
4. 通过 builder.Build() 构建应用程序。
5. 在 if (app.Environment.IsDevelopment()) 中使用 Swagger 和 SwaggerUI 中间件,只在当前环境下使用。
6. 使用 app.UseAuthorization() 添加授权中间件。
7. 使用 app.UseRouting() 开启路由功能中间件。
8. 使用 app.UseCors(“CorsSingnalR”) 设置跨域策略,使用名为 “CorsSingnalR” 的策略,允许来自任何来源的访问。
9. 使用 app.MapControllers() 将 MVC 控制器添加到请求处理管道中。
10. 使用 app.MapHub(“/chathub”) 添加 SignalR 路由,并将 ChatHub 类注册为路由,在客户端和服务器之间建立 WebSocket 连接
11. 最后,使用 app.Run() 启动应用程序。

using Microsoft.AspNetCore.SignalR;
using PracticeProjects.Logic;var builder = WebApplication.CreateBuilder(args); //创建asp.net core程序建造器,这个建造器允许我们配置应用程序的服务和中间件builder.Services.AddControllers();  //添加mvc控制器服务。用于处理http请求俄响应
builder.Services.AddSignalR();//用来实现实时通信builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();builder.Services.AddSingleton<ChatHub>();
//跨域设置
builder.Services.AddCors(op =>
{op.AddPolicy("CorsSingnalR",set =>{set.SetIsOriginAllowed(origin => true).AllowAnyHeader().AllowAnyMethod().AllowCredentials();});
});
var app = builder.Build();// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{app.UseSwagger();app.UseSwaggerUI();
}app.UseAuthorization();app.UseRouting();//中间件,用于开启路由功能。
app.UseCors("CorsSingnalR");//app.UseRouting(),之后app.UseCors设置跨域策略app.MapControllers();//将MVC控制器添加到请求处理管道中
app.MapHub<ChatHub>("/chathub");//添加SignalR路由;将SignalR的ChatHub类作为路由,在客户端与服务段建立WebSocket连接app.Run();//应用程序启动

ChatController.cs

  • List item
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using PracticeProjects.Logic;
using PracticeProjects.Model;namespace PracticeProjects.Controllers
{[Route("[controller]")][ApiController]public class ChatController : ControllerBase{private readonly ChatHub _chatHubContext;private readonly ILogger<ChatController> _logger;public ChatController(ChatHub chatHubContext, ILogger<ChatController> logger){_chatHubContext = chatHubContext;_logger = logger;}[Route("api/SendMsg")][HttpPost]public async Task<dynamic> SendMessage(ChatModel chat){await _chatHubContext.SendMessage(chat);return "发送成功";}}
}

方法类(ChatHub:继成Hub,Hub是SignalR中用于处理客户端与服务端双向通信的关键组件。)

using Microsoft.AspNetCore.SignalR;
using PracticeProjects.Model;namespace PracticeProjects.Logic
{/// <summary>/// 消息发送/// </summary>public class ChatHub : Hub{public async Task SendMessage(ChatModel chat){if(Clients!=null)await Clients.All.SendAsync("RecieveMessage", chat.name+":"+chat.content);}}
}

Model类(ChatModel):

namespace PracticeProjects.Model
{public class ChatModel{public string? name { get; set; }public string? content { get; set; }}
}
  • 前端关键部分代码(网上找的代码,用来模拟客户端)
    App.vue
<script setup>
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue';import { connection, connect, send, disconnect } from './utils/signalr';const msgInfo = reactive({ name: '张三', content: '' });
const receivemsglist = ref([]);//发送消息
const sendMsg = async () => {await send("SendMessage", msgInfo);
}onMounted(async () => {// 建立连接connect('http://localhost:5130/chathub'); // 开始连接await connection.start();// 注册方法(接收服务器推送过来的数据)connection.on('RecieveMessage', (res) => {console.log(`${new Date().toLocaleString()}】:从服务器同步消息成功!`);receivemsglist.value.push(res);});
});// 卸载
onBeforeUnmount(() => {// 断开连接disconnect();
});</script><template><div><a href="https://vitejs.dev" target="_blank"><img src="/vite.svg" class="logo" alt="Vite logo" /></a><a href="https://vuejs.org/" target="_blank"><img src="./assets/vue.svg" class="logo vue" alt="Vue logo" /></a></div><!-- <HelloWorld msg="Vite + Vue" /> --><div>姓名:<input type="text" v-model="msgInfo.name"><br>内容:<input type="text" v-model="msgInfo.content"><br><button type="button" @click="sendMsg">发送</button><br><table><tr><th>消息列表:</th></tr><tr v-for="(item, i) in receivemsglist" :key="i"><td>{{ item }}</td></tr></table></div>
</template><style scoped>
.logo {height: 6em;padding: 1.5em;will-change: filter;transition: filter 300ms;
}.logo:hover {filter: drop-shadow(0 0 2em #646cffaa);
}.logo.vue:hover {filter: drop-shadow(0 0 2em #42b883aa);
}
</style>

signalr.js

import * as signalR from '@microsoft/signalr';//如果需要身份验证
//.withUrl('/messageHub', {accessTokenFactory: () => sessionStorage.getItem('token')})
let connection;// 建立连接
async function start(url) {try {connection = new signalR.HubConnectionBuilder().withUrl(url)//跨域需要使用绝对地址.configureLogging(signalR.LogLevel.Information).withAutomaticReconnect() // 设置自动重连机制.build();} catch (err) {console.log(err);setTimeout(start, 10000);//错误重连}
}// 开始signalr连接
const connect = async (url) => {await start(url);console.log(`${new Date().toLocaleString()}:SignalR已连接成功!`);
};// 调用服务端方法 发送消息
async function send(methodName, param) {try {await connection.invoke(methodName, param);} catch (err) { console.error(err); }
}//断开连接
const disconnect = async () => {await connection.stop();console.log(`${new Date().toLocaleString()}:SignalR已断开连接!`);
};export { connection, connect, send, disconnect };

运行测试:

  1. 前后端代码启动
  2. 客户端请求服务端建立websocket连接:
    在这里插入图片描述
  3. 连接建立后,服务端可主动向前端推送消息
    在这里插入图片描述

上传的资源:

SignalR实时通信代码资源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/410049.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jmeter的文件参数化:CSV数据文件设置和_CSVRead函数

一、CSV数据文件设置 1、简介 CSV数据文件配置&#xff08;CSV Data Set Config&#xff09;可以将CSV文件中数据读入自定义变量中 Jmeter中CSV数据文件配置的界面如下图所示&#xff1a; 其中&#xff1a; &#xff08;1&#xff09;文件编码 文件的编码格式&#xff0c;与所…

【Python数据可视化】matplotlib之增加图形内容:设置图例、设置中文标题、设置网格效果

文章传送门 Python 数据可视化matplotlib之绘制常用图形&#xff1a;折线图、柱状图&#xff08;条形图&#xff09;、饼图和直方图matplotlib之设置坐标&#xff1a;添加坐标轴名字、设置坐标范围、设置主次刻度、坐标轴文字旋转并标出坐标值matplotlib之增加图形内容&#x…

JAVAEE初阶 文件IO(一)

这里写目录标题 一. 计算机中存储数据的设备1.1 CPU1.2 内存1.3 硬盘1.4 三种存储的区别 二.文件系统2.1 相对路径2.2 绝对路径2.3 .和..的含义2.4 例子2.5 everything工具 三.文件3.1 文本文件3.2 二进制文件 四. JAVA对于文件的API4.1 getParent getName getPath getAbsolute…

十六.触发器

触发器 1.触发器2.触发器的创建2.1创建触发器语法2.2代码举例 3.查看、删除触发器3.1查看触发器3.2删除触发器 4.触发器的优缺点4.1优点4.2缺点4.3注意点 5.练习 在实际开发中&#xff0c;我们经常会遇到这样的情况&#xff1a;有 2 个或者多个相互关联的表&#xff0c;如 商品…

瑞_Java开发手册_(四)安全规约

&#x1f64a;前言&#xff1a;本文章为瑞_系列专栏之《Java开发手册》的安全规约篇。由于博主是从阿里的《Java开发手册》学习到Java的编程规约&#xff0c;所以本系列专栏主要以这本书进行讲解和拓展&#xff0c;有需要的小伙伴可以点击链接下载。本文仅供大家交流、学习及研…

hardware simulation——框架搭建

目录 引子 代码风格约束 代码结构和模板 引子 前几天有人拿个word文档&#xff0c;问我怎么实现&#xff0c;概括一下就是用c实现数码管显示。 但是咱们肯定不做这么简单这么点&#xff0c;我打算做个开源的项目&#xff0c;可以一直更新底层软件库&#xff0c;和上层显示库…

IDEA无法解析jdk自带的类的解决办法

1.问题 IDEA在有些时候&#xff0c;会出现这个错误&#xff0c;就是jdk自带的java类找不到而报错。 例如下面的就是Object找不到&#xff0c;我们知道jdk自带的类是不用import包的&#xff0c;这里报错了&#xff0c;IDEA会提示你去导入类&#xff0c;其实这个提示也不是真正…

微服务治理:微服务断路器(微服务故障隔离模式)详解

微服务断路器是一种设计模式&#xff0c;可以保护系统免于级联故障&#xff0c;通过限制对故障服务的调用来实现。它的工作原理类似于电气断路器&#xff1a;当服务遇到问题时&#xff0c;它会切断请求流&#xff0c;使其有机会恢复&#xff0c;并防止其他服务被压垮。 工作原…

vue3__Provide / Inject (依赖注入)和mixins

一、 Provide提供和Inject 注入 Provide提供 <script setup> import { provide } from vueprovide(/* 注入名 */ message, /* 值 */ hello!) </script> 例如父组件中提供方法 <template> <div class"home">dfhualsf<div><button…

SqlAlchemy使用教程(二) 入门示例及编程步骤

SqlAlchemy使用教程(一) 原理与环境搭建SqlAlchemy使用教程(三) CoreAPI访问与操作数据库详解 二、入门示例与基本编程步骤 在第一章中提到&#xff0c;Sqlalchemy提供了两套方法来访问数据库&#xff0c;由于Sqlalchemy 官方文档结构有些乱&#xff0c;对于ORM的使用步骤的描…

transbigdata笔记:其他方法

1 出租车相关 1.1 taxigps_to_od 提取出租车OD信息 transbigdata.taxigps_to_od(data, col[VehicleNum, Stime, Lng, Lat, OpenStatus]) 输入出租车GPS数据&#xff0c;提取OD信息 data出租车GPS数据col[VehicleNum, Time, Lng, Lat, OpenStatus]五列 比如GPS数据长这样&am…