在Volo.Abp微服务中使用SignalR

news2024/9/24 17:15:33

假设需要通过SignalR发送消息通知,并在前端接收消息通知的功能

创建SignalR服务

在项目中引用

abp add-package Volo.Abp.AspNetCore.SignalR

在Module文件中添加对模块依赖

[DependsOn(
    ...
    typeof(AbpAspNetCoreSignalRModule)
    )]
public class IdentityApplicationModule : AbpModule

创建接口INotificationHub

public interface INotificationHub
{
    // 发送消息
    Task ReceiveTextMessageAsync(SendNotificationDto input);
}

也可以不创建接口,AbpHub类,定义了泛型和非泛型的类型。

创建NotificationHub类,继承AbpHub。
可以直接继承Microsoft.AspNetCore.SignalR.Hub,但是这样就不能使用已注入的属性,如 CurrentUser

/// <summary>
/// SignalR消息Hub
/// </summary>
[HubRoute("signalr/Identity/notification")]
[Authorize]
[DisableAuditing]
public class NotificationHub : AbpHub<INotificationHub>
{

}

发送SignalR消息

在需要调用的地方注入IHubContext,并初始化

private readonly IHubContext<NotificationHub, INotificationHub> _hubContext;
public NotificationAppService(IHubContext<NotificationHub, INotificationHub> hubContext) 
{
    _hubContext = hubContext;
}

使用下面的方式发送给指定用户或者所有用户

public async Task SendMessageToUsersAsync(List<string> userIds, SendNotificationDto sendNotificationDto)
{
    await _hubContext.Clients
        .Users(userIds.AsReadOnly().ToList())
        .ReceiveTextMessageAsync(sendNotificationDto);
}


public async Task SendMessageToAllAsync(SendNotificationDto sendNotificationDto)
{
    await _hubContext.Clients.All.ReceiveBroadCastMessageAsync(sendNotificationDto);
}

配置Ocelet网关

为/signalr/identity/路由创建转发规则

当SignalR开始连接时,首先发送协商协议请求,协商协议返回availableTransports告诉客户端支持哪些协议,以及connetcionId和connectionToken,这两个值会在后续的连接中使用。

在这里插入图片描述

在当前路由配置下,请求地址是:/signalr/identity/negotiate,此http请求会通过网关转发到IdentityServer。

在Gateway项目的appsettings.json中配置网关转发规则,如下:

"Routes": [
    {
      "DownstreamPathTemplate": "/signalr/identity/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 44368
        }
      ],
      "UpstreamPathTemplate": "/signalr/identity/{everything}",
      "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ]
    },
    ...

除此之外还要配置ws协议的转发规则,SignalR首先尝试建立WebSocket连接,WebSocket是 SignalR的最佳传输方式,配置如下:

  {
    "DownstreamPathTemplate": "/signalr/identity/{everything}",
    "DownstreamScheme": "ws",
    "Priority": 1,
    "DownstreamHostAndPorts": [
      {
        "Host": "localhost",
        "Port": 44368
      }
    ],
    "UpstreamPathTemplate": "/signalr/identity/{everything}",
    "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ]
  },

尽量使用kestrel运行网关程序,IIS7.0之前不支持websocket,若使用IIS请确保Websocket功能已经打开。
在UseOcelot()之前添加UseWebSockets(),以便网关能接收ws或wss协议的请求。若不加这个网关会在转发时返回499错误码。

app.UseWebSockets();
app.UseOcelot().Wait();

创建SignalR客户端

客户端安装取决于你的UI框架/客户端类型。若使用Asp.NetCore MVC或Razor,请参考abp官方文档
这里补充其他UI框架的使用方法。在webpackage项目中添加对SignalR的依赖

yarn add @microsoft/signalr

创建一个hubConnection
在main.js中添加如下代码

const hubConnection: signalR.HubConnection = new signalR.HubConnectionBuilder()
  .withUrl(baseURL + requestUrl, {
    headers: header,
    accessTokenFactory: () => getAccessToken(),
    transport: signalR.HttpTransportType.WebSockets,
    logMessageContent: true,
    logger: signalR.LogLevel.Information,
  })
  .withAutomaticReconnect()
  .withHubProtocol(new signalR.JsonHubProtocol())
  .build();

accessTokenFactory回调用于获取access_token的,会在每次请求时调用以保证获取最新的access_token。

连接服务

在需要使用的地方调用hubConnection方法

hubConnection.start() //开始连接
hubConnection.stop()  //停止连接

订阅消息

hubConnection.on("ReceiveTextMessage", (newMsg) => {
  console.info("new msg recived!", newMsg)
});

身份验证

WebSockets不支持自定义Header,所以不能使用Authorization,需要使用access_token参数传递令牌

客户端

在客户端中配置getAccessToken,如下:

const getAccessToken: Function = (): string => {
  var token = UserModule.token !== undefined ? UserModule.token : ""; 
  return token;
}

UserModule.token是当前登录用户的token,需要在登录成功后保存到UserModule中。

服务端

在服务端中,若已经使用了IdentityServer,则需要在Startup中配置IdentityServerAuthentication,配置如下:

context.Services.AddAuthentication("Bearer")
    .AddIdentityServerAuthentication(options =>
    {
        options.Authority = configuration["AuthServer:Authority"];
        options.ApiName = configuration["AuthServer:ApiName"];
        options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]);
        options.TokenRetriever = (request) =>
        {
            var path = request.Path;
            if (path.StartsWithSegments("/signalr"))
            {
                var accessToken = request.Query["access_token"].FirstOrDefault();

                if (!accessToken.IsNullOrWhiteSpace())
                {
                    return accessToken;
                }
            }
            return TokenRetrieval.FromAuthorizationHeader().Invoke(request);

        };                  
    });
    

如果你适用IISExpress运行项目,注意此时SignalR的url参数可能过长而报告404.15 - Query String Too Long,IIS默认限制是2048,需要在C:\Windows\System32\inetsrv\config\applicationHost.config中配置maxQueryString规则,如下:

<configuration>
   <system.webServer>
      <security>
         <requestFiltering>
             <requestLimits maxQueryString="4096" />
         </requestFiltering>
      </security>
   </system.webServer>
</configuration>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaEE 面试常见问题

一、常见的 ORM 框架有哪些&#xff1f; 1.Mybatis Mybatis 是一种典型的半自动的 ORM 框架&#xff0c;所谓的半自动&#xff0c;是因为还需要手动的写 SQL 语句&#xff0c;再由框架根据 SQL 及 传入数据来组装为要执行的 SQL 。其优点为&#xff1a; 1. 因为由程序员…

便捷省心的手机直播影视工具,畅享轻松电视娱乐时光

便捷省心的手机直播影视工具&#xff0c;畅享轻松电视娱乐时光 在快节奏的现代生活中&#xff0c;我们常常渴望能够以简单、省心的方式消遣自己&#xff0c;享受高品质的电视娱乐。幸运的是&#xff0c;随着技术的进步&#xff0c;便捷省心的手机直播影视工具应运而生。这些工…

原来设计师都在6个网站找素材~

设计师都在用的这些设计素材网站你知道吗&#xff1f;免费、商用真的很香&#xff0c;一定要收藏~ 菜鸟图库 https://www.sucai999.com/?vNTYxMjky 菜鸟图库是一个非常大的素材库&#xff0c;站内包含设计、办公、自媒体、图片、电商等各行业素材。网站主要为新手设计师提供…

网站无法访问的常见原因

有多种问题可能会阻止用户访问您的网站。本文将解决无法访问网站&#xff0c;且没有错误消息指示确切问题的情况&#xff0c;希望对您有所帮助。 无法访问网站的常见原因有&#xff1a; (1)DNS 设置不正确。 (2)域名已过期。 (3)空白或没有索引文件。 (4)网络连接问题。 DNS 设…

bash的特性(二)IO重定向与管道

bash的I/O重定向及管道 一、概述 在shell中&#xff0c;最常使用的fd(file descriptor)有三个&#xff0c;标准输入&#xff0c;标准输出&#xff0c;错误输出。进程用文件描述符来管理打开的文件。 名称 文件描述符 标准输入&#xff08;stdin) 0 键盘&#xff0c;也可以…

分布式应用:ELFK集群部署

目录 一、理论 1.ELFK集群 2.filebeat 3.部署ELK集群 二、实验 1. ELFK集群部署 三、总结 一、理论 1.ELFK集群 &#xff08;1&#xff09;概念 ELFK集群部署&#xff08;FilebeatELK&#xff09;&#xff0c;ELFK ES logstashfilebeatkibana 。 数据流 架构 2.fi…

LangChain+ChatGLM整合LLaMa模型(二)

开源大模型语言LLaMa LLaMa模型GitHub地址添加LLaMa模型配置启用LLaMa模型 LangChainChatGLM大模型应用落地实践&#xff08;一&#xff09; LLaMa模型GitHub地址 git lfs clone https://huggingface.co/huggyllama/llama-7b添加LLaMa模型配置 在Langchain-ChatGLM/configs/m…

第三方软件测评机构如何搭建测试环境?测试报告收费标准

**  在软件产品周期中&#xff0c;软件测试环境是一个非常重要的组成部分它提供了一个模拟真实生产环境的虚拟环境&#xff0c;用于测试和验证软件的功能和性能。一个好的软件测试环境可以帮助开发团队更好地发现和解决问题&#xff0c;提高软件的质量和可靠性。 一、第三方…

EDM邮件打开率标准,如何提高EDM营销打开率?

EDM邮件打开率和转化率平均水平是多少?如何做高转化率的EDM邮件营销? 随着许多企业参与EDM营销&#xff0c;如何提高EDM邮件打开率成为一个关键问题。本文将介绍EDM邮件打开率标准&#xff0c;并提供一些建议&#xff0c;帮助您提升EDM营销打开率&#xff0c;吸引更多潜在客…

便捷就医新选择,深度解析诊所小程序的功能要求

随着移动互联网的快速发展&#xff0c;越来越多的诊所选择开发诊所小程序来提供便捷的医疗服务。诊所小程序是一种基于微信平台的轻量级应用程序&#xff0c;为用户提供在线挂号、诊疗记录查看、医生咨询等功能。本文将介绍诊所小程序的功能要求&#xff0c;以帮助诊所更好地了…

银河麒麟V10 QtCreator安装配置说明(断网离线)

文章目录 1.安装要求:2.安装Qt1.安装要求: 拥有Qt软件安装包qt5.12-arm链接:https://pan.baidu.com/s/1FJerT6SckfjABxAn60rsrA?pwd=mfi6 提取码:mfi6 2.安装Qt 1)拷贝Qt软件包qt5.12-arm至系统/home/kylin/桌面 2)安装Qt软件包 cd /home/kylin/qt5.12-arm/桌面 su…

CLion和VS中avcodec_receive_frame()获取结果不同

1. 介绍 在提取音视频文件中音频的PCM数据时&#xff0c;使用avcodec_receive_frame()函数进行解码时&#xff0c;遇到了一些问题&#xff0c;代码在Visual Studio 2022中运行结果符合预期&#xff0c;但是在CLion中运行时&#xff0c;获取的AVFrame有错误&#xff0c;和VS中获…

HTTP——六、HTTP首部

HTTP首部 一、HTTP报文首部HTTP 请求报文HTTP 响应报文 二、HTTP 首部字段1、HTTP 首部字段传递重要信息2、HTTP 首部字段结构3、4 种 HTTP 首部字段类型4、HTTP/1.1 首部字段一览5、非 HTTP/1.1 首部字段6、End-to-end 首部和 Hop-by-hop 首部 三、HTTP/1.1 通用首部字段1、Ca…

HCIP的mgre小实验

实验要求&#xff1a; 第一步&#xff1a;拓扑的搭建 第二步&#xff1a;路由、IP的配置&#xff1a; r1: <Huawei>sys Enter system view, return user view with CtrlZ. [Huawei]sys r1 [r1]int g 0/0/0 [r1-GigabitEthernet0/0/0]ip add 192.168.1.2 24 [r1-Gigabi…

TCP三次握手,四次挥手理解

1. 三次握手 *三次握手&#xff08;Three-way Handshake&#xff09;*其实就是指建立一个TCP连接时&#xff0c;需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实…

【双指针_移动零_C++】

题目解析 移动零 nums [0,1,0,3,12] [1,3,12,0,0]算法原理 数组划分&#xff08;数组分块&#xff09; 双指针算法&#xff08;利用数组下标来充当指针&#xff09;使用两个指针的作用&#xff1a; cur指针&#xff1a;从左往右扫描数组&#xff0c;就是遍历数组。 dest指针…

【ES】笔记-let 声明及其特性

let 声明及其特性 声明变量 变量赋值、也可以批量赋值 let a;let b,c,d;let e100;let f521,giloveyou,h[];变量不能重复声明 let star罗志祥;let star小猪;块级作用域&#xff0c;let声明的变量只在块级作用域内有效 {let girl周杨青;}console.log(girl)注意&#xff1a;在 i…

flutter开发实战-实现css线性渐变转换flutter渐变LinearGradient功能

flutter开发实战-实现css线性渐变转换flutter渐变LinearGradient功能 在之前项目开发中&#xff0c;遇到更换样式&#xff0c;由于从服务器端获取的样式均为css属性值&#xff0c;需要将其转换成flutter类对应的属性值。这里只处理线性渐变linear-gradient 比如渐变 “linear-…

macOS install redis遇到的bug(tar包,homebrew安装,守护进程redis.conf配置)

官网下载tar包再make install 首先是sudo make test的时候一直报 !!! WARNING The following tests failed: *** [err]: trim on SET with big value in tests/unit/type/string.tcl Expected [r memory usage key] < 42000 (context: type source line 478 file /usr/loca…

【二开】前端项目二开技巧 组件相关dependencies

【二开】前端项目二开技巧 组件相关dependencies 二开 依赖的组件 dependencies 方案一 1.直接去 项目下 node_modules目录里改对应的组件代码 2.清理缓存 rimraf node_modules/.cache/ && rimraf node_modules/.vite 3.启动项目生效 方案二&#xff08;推荐&#xf…