在Volo.Abp微服务中使用SignalR
假设需要通过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>相关文章:
在Volo.Abp微服务中使用SignalR
假设需要通过SignalR发送消息通知,并在前端接收消息通知的功能 创建SignalR服务 在项目中引用 abp add-package Volo.Abp.AspNetCore.SignalR在Module文件中添加对模块依赖 [DependsOn(...typeof(AbpAspNetCoreSignalRModule))] public class IdentityApplicati…...
数据可视化(七)常用图表的绘制
1. #seaborn绘制常用图表 #折线图 #replot(x,y,kind,data) #lineplot(x,y,data) #直方图 #displot(data,rug) #条形图 #barplot&…...
【ARM 常见汇编指令学习 8 - dsb sy 指令及 dsb 参数介绍】
文章目录 ARM dsb sy 指令 上篇文章:ARM 常见汇编指令学习 7 - LDR 指令与LDR伪指令及 mov指令 下篇文章:ARM 常见汇编指令学习 9 - 缓存管理指令 DC 与 IC ARM dsb sy 指令 数据同步屏障是一种特殊类型的内存屏障。 只有当DSB指令执行完毕后ÿ…...
YOLOv5本地模型训练报错解决
报错解决 页面文件太小,无法完成操作 训练过程中,发生下图所示的报错,同时pycharm崩溃 1. 更改虚拟内存 进入高级系统设置,应该都会进,就不说过程了 设置虚拟内存大小 2. 减小占用内容大小 新建一个fixNvPe.py程序…...
tomcat p12证书另存为nginx .crt证书和.key私钥
tomcat p12证书另存为nginx .crt证书和.key私钥 Tomcat使用的.pfx或.keystore文件都是私钥及公钥证书一起的,通过pin保证安全;nginx只需要使用.pem或.crt公钥证书文件和.key私钥即可,如果原ssl证书不方便重新下载,在已有tomcat证…...
Docker的userland-proxy
前言 Docker针对端口映射前后有两种方案,一种是1.7版本之前docker-proxyiptables DNAT 的方式;另一种则是1.7版本(及之后)提供的完全由iptables DNAT实现的端口映射。不过在目前docker 1.9.1中,前一种方式依旧是默认方式。但是从Docker 1.7版…...
uniapp封装request请求
在基础文件里面创建一个api文件 在创建两个 js文件 http.js 里面封装 request 请求 let baseUrl https://white.51.toponet.cn; //基地址 export const request (options {}) > {//异步封装接口,使用Promise处理异步请求return new Promise((resolve, reject…...
Go如何构建高效API接口| 青训营
Go语言作为一个高效的静态类型语言,在构建API服务时也表现出了很大的优势。本文将介绍如何使用Go语言构建高效的API服务,帮助开发者更好地应对日益增长的API需求。 一、选择适合的框架 首先,选择适合的框架是构建高效API服务的重要一步。在…...
【云原生K8s】二进制部署单master K8s+etcd集群
一、实验设计 mater节点master01192.168.190.10kube-apiserver kube-controller-manager kube-scheduler etcd node节点node01192.168.190.20kubelet kube-proxy docker (容…...
TRUNC(截取)函数的用法
TRUNC函数在Oracle中用于截断日期、时间或数字的精度。其语法如下: 截取数字: TRUNC(number [, precision])其中: number 表示要截断的数字。 precision表示截断的精度。可以是负数、整数或者默认为空。正数表示保留小数位数,负…...
IELAB-网络工程师的路由答疑10问(1)
各位同学,我相信对于许多新学习的同学而言,在刚接触该的时候总会产生许多问题,今天 我们就简单讲解一下常见的几种问题: 什么是路由? 简单来讲,路由通常发生在网络层,为什么呢?首先…...
OpenLayers入门,OpenLayers加载TopoJson数据,使用行政区划边界作为示例
专栏目录: OpenLayers入门教程汇总目录 前言 本章讲解一下OpenLayers如何加载解析TopoJson格式的数据。 TopoJson介绍 TopoJson是用于表示地理空间数据的格式。是GeoJson格式的改进版,相比 GeoJSON 直接使用 Polygon、Point 之类的几何体来表示图形的方法,TopoJSON 中的…...
【图像去噪】基于原始对偶算法优化的TV-L1模型进行图像去噪研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
RISC-V基础之函数调用(五)函数递归调用及函数参数数量溢出(超出现有寄存器个数)约定(包含实例)
首先先解释一下栈在函数调用中的作用,更详细的部分请参照考研复习之数据结构笔记(五)栈和队列(上)(包含栈的相关内容)_管二狗赶快去工作!的博客-CSDN博客 函数嵌套调用栈的作用是用…...
力扣:48. 旋转图像(Python3)
题目: 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 来源:力扣(LeetCode) 链接&…...
HarmonyOS应用开发者基础与高级认证题库——中级篇
系列文章目录 HarmonyOS应用开发者基础与高级认证题库——基础篇 HarmonyOS应用开发者基础与高级认证题库——中级篇 文章目录 系列文章目录前言一、判断二、单选三、多选 前言 今天刚换了台果子手机就收到了华子鸿蒙开发认证邀请(认证链接)࿰…...
Python中实现多个列表、字典、元组、集合的连接
目录 目录 前言 一、列表 1、运算符 2、extend()方法 3、解包操作 * 二、字典 1、update()方法 2、解包操作 ** 三、元组 1、 运算符 2、解包操作 * 四、集合 1、union方法 2、| 运算符 3、解包操作 * 五、不同类…...
1005 继续(3n+1)猜想
描述 卡拉兹(Callatz)猜想已经在1001中给出了描述。在这个题目里,情况稍微有些复杂。 当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数。例如对 n3 进行验证的时候,我们需要计算 3、5、8、4、…...
基于图片、无人机、摄像头拍摄进行智能检测功能
根据要求进行无人机拍摄的视频或图片进行智能识别,开发过程需要事项 1、根据图片案例进行标记,进行模型训练 2、视频模型训练 开发语言为python 根据需求功能进行测试结果如下 根据车辆识别标记进行的测试结果截图 测经过查看视频 8月1日...
Boost开发指南-4.2ignore_unused
ignore_unused 编写代码的过程中有时会出现一些暂时用不到但又必须保留的变量,GCC等编译器会对此发出警告,使用-Wunused可以关闭这些警告消息,不过这也有可能导致潜在的隐患。古老的办法是使用(void)var的形式来“使用”一下变量,…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
