.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.mfbz.cn/a/323088.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript之函数、数组作业

1.计算用户指定的数值内的奇数和&#xff0c;例如用户输入的是10&#xff0c;则计算1 3 5 7 9的和&#xff1b; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content&qu…

Mr_HJ / form-generator项目学习-增加自定义的超融组件(二)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/n…

Docker镜像构建优化及上传

前言 Dockerfile 是一个文本格式的配置文件&#xff0c; 用户可以使用 Dockerfile 来快速创建自定义的镜像&#xff0c;另外&#xff0c;使 用 Dockerfile 去构建镜像好比使用 pom 去构建 maven 项目一样&#xff0c;有异曲同工之妙 一.Dockerfile镜像构建 1.Dockerfile基本…

数据库知识汇总之MySQL

目录 MySQL数据库特点MySQL下载MySQL配置文件初始化MySQL配置安装MySQL服务 启动MySQL服务登录数据库修改数据库登录密码MySQL错误代码1130 MySQL数据库特点 MySQL是一个开源关系型数据库管理系统(RDBMS)&#xff0c;由Oracle公司维护和开发。它使用SQL语言进行数据库管理和操…

Linux下安装Mysql8.0版本【保姆级】

&#x1f95a;今日鸡汤&#x1f95a; 等风来&#xff0c;不如追风去。 ——《一禅小和尚》 目录 &#x1f37f;1.Linux查看glibc版本 &#x1f9c2;2.mysql下载 &#x1f9c8;3.上传到指定目录 &#x1f953;4.解压并操作 &#x1f32d;5.启动mysql 1.Linux查看glibc版本…

腾讯实验平台基于 StarRocks 构建湖仓底座

作者&#xff1a; 腾讯大数据平台部科学实验中心Tech Lead、专家工程师 马金勇博士 腾讯大数据平台部科学实验中心数据负责人、专家工程师 胡明杰 StarRocks Contributor、腾讯高级工程师 刘志行 在 2022 年&#xff0c;腾讯 A/B Test 团队启动了海外商业化版本 ABetterChoice …

常用文件文档能做二维码吗?多种文件在线做二维码的方法

二维码是现在工作和生活中随处可见&#xff0c;可以用来展现很多不同的内容。现在很多下发通知的文件、教程或者其他文件内容&#xff0c;也会制作成二维码图片后&#xff0c;让其他人通过扫码来获取文件内容。最简单的制作方法就是通过二维码生成器来制作&#xff0c;支持多种…

【Py/Java/C++三种语言详解】LeetCode每日一题240115【链表】LeetCode82、删除排序链表中的重复节点II

文章目录 题目链接题目描述解题思路代码pythonJavaC时空复杂度 华为OD算法/大厂面试高频题算法练习冲刺训练 题目链接 LeetCode82、删除排序链表中的重复节点II 题目描述 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不…

#AIGC##VDB# 【一篇入门VDB】矢量数据库-从技术介绍到选型方向

文章概览&#xff1a; 这篇文章深入探讨了矢量数据库的基本概念、工作原理以及在人工智能领域的广泛应用。 首先&#xff0c;文章解释了矢量的数学和物理学概念&#xff0c;然后引入了矢量在数据科学和机器学习中的应用。随后&#xff0c;详细介绍了什么是矢量数据库&#xff0…

【unity学习笔记】语音驱动blendershape

1.导入插件 https://assetstore.unity.com/packages/tools/animation/salsa-lipsync-suite-148442 1.选择小人&#xff0c;点击添加组件 分别加入组件&#xff1a; SALSA EmoteR Eyes Queue Processor&#xff08;必须加此脚本&#xff09;&#xff1a;控制前三个组件的脚本。…

基于深度学习的桃子熟度与大小智能检测

基于深度学习的桃子熟度与大小智能检测 基于深度学习的桃子熟度与大小智能检测引言1. 环境搭建与准备2. 数据准备3. 模型准备4. 训练准备5. 服务器端部署结语 基于深度学习的桃子熟度与大小智能检测 引言 随着时代的快速发展&#xff0c;人工智能时代为中国农业带来了新的机遇…

idea修改pom.xml没有重新导入maven的按钮

问题描述&#xff1a; IDEA修改pom.xml配置以后&#xff0c;不会展示 Load Maven Changes弹窗。 解决方法&#xff1a; 方式一、pom.xml右键&#xff0c;Maven--Run Maven--Reimport。但我感觉这个太麻烦了。 方式2、选择Building Tool Settings&#xff0c;点击Auto-Reload …

python -- str 字符串相减

从一个字符串中减去另一个字符串&#xff0c;得到一个新的字符串结果 replace() 方法 host_ip hello world host world ip host_ip.replace(host, "") print(ip)re.sub() 方法 import rehost_ip hello world host world ip re.sub(host, "", host_…

IDEA 启动错误提示:Command line is too long. Shorten command line

IDEA 启动错误提示&#xff1a;Command line is too long. Shorten command line Command line is too long. Shorten command line IDEA 启动错误提示&#xff1a;Command line is too long. Shorten command line快速修改原因解释 快速修改 Edit Configurations->configu…

IPv6路由综合运用

一、基础配置: SWA: sw1(config)#host swA swA(config)#ipv6 ena swA(config)# vlan 100 swA(config-vlan100)#int vlan 100 swA(config-if-vlan100)#ipv6 ena swA(config-vlan100)#ip add 172.16.1.1 255.255.255.252 swA(config-if-vlan100)#int e1/0/24 swA(conf…

C函数详解 | 函数的作用、定义与声明、函数的调用、函数与指针

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

生成式对抗网络GAN

Generative Adversarial Nets由伊恩古德费洛&#xff08;Ian J.Goodfellow&#xff09;等人于2014年发表在Conference on Neural Information Processing Systems (NeurIPS)上。NeurIPS是机器学习和计算神经科学领域的顶级国际学术会议之一。 1. GAN在哪些领域大放异彩 图像生…

远程访问及控制

文章目录 远程访问及控制一、SSH远程管理1、SSH&#xff08;Secure Shell&#xff09;协议定义2、SSH的优点3、OpenSSHell 二、配置OpenSSH服务端1、sshd_config配置文件的常用选项2、sshd服务支持的两种验证方式2.1 密码验证2.2 秘钥对验证 三、SSH客户端程序的使用1、基本用法…

C# OpenCvSharp DNN 部署yolov3目标检测

目录 效果 yolov3.cfg 项目 代码 下载 C# OpenCvSharp DNN 部署yolov3目标检测 效果 yolov3.cfg [net] # Testing #batch1 #subdivisions1 # Training batch16 subdivisions1 width416 height416 channels3 momentum0.9 decay0.0005 angle0 saturation 1.5 exposure 1…
最新文章