当前位置: 首页 > news >正文

在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发送消息通知&#xff0c;并在前端接收消息通知的功能 创建SignalR服务 在项目中引用 abp add-package Volo.Abp.AspNetCore.SignalR在Module文件中添加对模块依赖 [DependsOn(...typeof(AbpAspNetCoreSignalRModule))] public class IdentityApplicati…...

数据可视化(七)常用图表的绘制

1. #seaborn绘制常用图表 #折线图 #replot&#xff08;x&#xff0c;y&#xff0c;kind&#xff0c;data&#xff09; #lineplot&#xff08;x&#xff0c;y&#xff0c;data&#xff09; #直方图 #displot&#xff08;data&#xff0c;rug&#xff09; #条形图 #barplot&…...

【ARM 常见汇编指令学习 8 - dsb sy 指令及 dsb 参数介绍】

文章目录 ARM dsb sy 指令 上篇文章&#xff1a;ARM 常见汇编指令学习 7 - LDR 指令与LDR伪指令及 mov指令 下篇文章&#xff1a;ARM 常见汇编指令学习 9 - 缓存管理指令 DC 与 IC ARM dsb sy 指令 数据同步屏障是一种特殊类型的内存屏障。 只有当DSB指令执行完毕后&#xff…...

YOLOv5本地模型训练报错解决

报错解决 页面文件太小&#xff0c;无法完成操作 训练过程中&#xff0c;发生下图所示的报错&#xff0c;同时pycharm崩溃 1. 更改虚拟内存 进入高级系统设置&#xff0c;应该都会进&#xff0c;就不说过程了 设置虚拟内存大小 2. 减小占用内容大小 新建一个fixNvPe.py程序…...

tomcat p12证书另存为nginx .crt证书和.key私钥

tomcat p12证书另存为nginx .crt证书和.key私钥 Tomcat使用的.pfx或.keystore文件都是私钥及公钥证书一起的&#xff0c;通过pin保证安全&#xff1b;nginx只需要使用.pem或.crt公钥证书文件和.key私钥即可&#xff0c;如果原ssl证书不方便重新下载&#xff0c;在已有tomcat证…...

Docker的userland-proxy

前言 Docker针对端口映射前后有两种方案&#xff0c;一种是1.7版本之前docker-proxyiptables DNAT 的方式&#xff1b;另一种则是1.7版本(及之后)提供的完全由iptables DNAT实现的端口映射。不过在目前docker 1.9.1中&#xff0c;前一种方式依旧是默认方式。但是从Docker 1.7版…...

uniapp封装request请求

在基础文件里面创建一个api文件 在创建两个 js文件 http.js 里面封装 request 请求 let baseUrl https://white.51.toponet.cn; //基地址 export const request (options {}) > {//异步封装接口&#xff0c;使用Promise处理异步请求return new Promise((resolve, reject…...

Go如何构建高效API接口| 青训营

Go语言作为一个高效的静态类型语言&#xff0c;在构建API服务时也表现出了很大的优势。本文将介绍如何使用Go语言构建高效的API服务&#xff0c;帮助开发者更好地应对日益增长的API需求。 一、选择适合的框架 首先&#xff0c;选择适合的框架是构建高效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中用于截断日期、时间或数字的精度。其语法如下&#xff1a; 截取数字&#xff1a; TRUNC(number [, precision])其中&#xff1a; number 表示要截断的数字。 precision表示截断的精度。可以是负数、整数或者默认为空。正数表示保留小数位数&#xff0c;负…...

IELAB-网络工程师的路由答疑10问(1)

各位同学&#xff0c;我相信对于许多新学习的同学而言&#xff0c;在刚接触该的时候总会产生许多问题&#xff0c;今天 我们就简单讲解一下常见的几种问题&#xff1a; 什么是路由&#xff1f; 简单来讲&#xff0c;路由通常发生在网络层&#xff0c;为什么呢&#xff1f;首先…...

OpenLayers入门,OpenLayers加载TopoJson数据,使用行政区划边界作为示例

专栏目录: OpenLayers入门教程汇总目录 前言 本章讲解一下OpenLayers如何加载解析TopoJson格式的数据。 TopoJson介绍 TopoJson是用于表示地理空间数据的格式。是GeoJson格式的改进版,相比 GeoJSON 直接使用 Polygon、Point 之类的几何体来表示图形的方法,TopoJSON 中的…...

【图像去噪】基于原始对偶算法优化的TV-L1模型进行图像去噪研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

RISC-V基础之函数调用(五)函数递归调用及函数参数数量溢出(超出现有寄存器个数)约定(包含实例)

首先先解释一下栈在函数调用中的作用&#xff0c;更详细的部分请参照考研复习之数据结构笔记&#xff08;五&#xff09;栈和队列&#xff08;上&#xff09;&#xff08;包含栈的相关内容&#xff09;_管二狗赶快去工作&#xff01;的博客-CSDN博客 函数嵌套调用栈的作用是用…...

力扣:48. 旋转图像(Python3)

题目&#xff1a; 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&…...

HarmonyOS应用开发者基础与高级认证题库——中级篇

系列文章目录 HarmonyOS应用开发者基础与高级认证题库——基础篇 HarmonyOS应用开发者基础与高级认证题库——中级篇 文章目录 系列文章目录前言一、判断二、单选三、多选 前言 今天刚换了台果子手机就收到了华子鸿蒙开发认证邀请&#xff08;认证链接&#xff09;&#xff0…...

Python中实现多个列表、字典、元组、集合的连接

目录 目录 前言 一、列表 1、运算符 2、extend&#xff08;&#xff09;方法 3、解包操作 * 二、字典 1、update&#xff08;&#xff09;方法 2、解包操作 ** 三、元组 1、 运算符 2、解包操作 * 四、集合 1、union方法 2、| 运算符 3、解包操作 * 五、不同类…...

1005 继续(3n+1)猜想

描述 卡拉兹(Callatz)猜想已经在1001中给出了描述。在这个题目里&#xff0c;情况稍微有些复杂。 当我们验证卡拉兹猜想的时候&#xff0c;为了避免重复计算&#xff0c;可以记录下递推过程中遇到的每一个数。例如对 n3 进行验证的时候&#xff0c;我们需要计算 3、5、8、4、…...

基于图片、无人机、摄像头拍摄进行智能检测功能

根据要求进行无人机拍摄的视频或图片进行智能识别&#xff0c;开发过程需要事项 1、根据图片案例进行标记&#xff0c;进行模型训练 2、视频模型训练 开发语言为python 根据需求功能进行测试结果如下 根据车辆识别标记进行的测试结果截图 测经过查看视频 8月1日...

Boost开发指南-4.2ignore_unused

ignore_unused 编写代码的过程中有时会出现一些暂时用不到但又必须保留的变量&#xff0c;GCC等编译器会对此发出警告&#xff0c;使用-Wunused可以关闭这些警告消息&#xff0c;不过这也有可能导致潜在的隐患。古老的办法是使用(void)var的形式来“使用”一下变量&#xff0c…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...