ASP.NET Zero+Angular下SignalR如何通过HTTP地址授权并使用独立WS地址连接
适配Azure APIM的SignalR配置解决方案
1. 新增配置项
首先在AppConsts中新增WebSocket专属基础地址,符合Azure APIM要求的路由区分规则:
// AppConsts.ts 新增配置 export class AppConsts { // 原有配置保持不变 remoteServiceBaseUrl: string; appBaseUrl: string; // 按APIM规则配置WebSocket专属地址,示例为wss://{base_url}/ws(后缀可根据你的APIM规则调整) signalRWebSocketBaseUrl: string; }
提前在Azure APIM中完成对应路由配置,保证HTTP接口和WebSocket路由路径不一致即可。
2. 修改SignalRHelper逻辑
覆盖ABP默认的SignalR连接规则,保留原有授权逻辑的同时,替换WebSocket连接地址,修改后代码如下:
import { AppConsts } from '@shared/AppConsts'; import { LocalStorageService } from '@shared/utils/local-storage.service'; export class SignalRHelper { static initSignalR(callback: () => void): void { new LocalStorageService().getItem( AppConsts.authorization.encrptedAuthTokenName, function (err, value) { let encryptedAuthToken = value?.token; abp.signalr = { autoConnect: false, // 保持原有Angular zone外运行的逻辑 connect: undefined, hubs: undefined, qs: encryptedAuthToken ? AppConsts.authorization.encrptedAuthTokenName + '=' + encodeURIComponent(encryptedAuthToken) : '', // 授权协商请求仍走原有HTTP接口地址,满足授权要求 remoteServiceBaseUrl: AppConsts.remoteServiceBaseUrl, startConnection: undefined, url: '/signalr', // 新增钩子,替换WebSocket连接地址为专属路由 beforeConnect: (connection) => { connection.baseUrl = `${AppConsts.signalRWebSocketBaseUrl}/signalr`; } }; let script = document.createElement('script'); script.onload = () => { callback(); }; script.src = AppConsts.appBaseUrl + '/assets/abp/abp.signalr-client.js'; document.head.appendChild(script); } ); } }
如果你使用的ABP版本不支持beforeConnect钩子,可直接重写连接创建逻辑,完全自定义连接规则:
// 替换上述abp.signalr配置为以下内容即可 abp.signalr.startConnection = function (url, configureConnection) { return new Promise((resolve, reject) => { const builder = new signalR.HubConnectionBuilder() .withUrl(`${AppConsts.signalRWebSocketBaseUrl}${url}`, { // 保持原有加密token授权逻辑不变 accessTokenFactory: () => encryptedAuthToken }) .withAutomaticReconnect(); if (configureConnection) configureConnection(builder); const connection = builder.build(); connection.start() .then(() => resolve(connection)) .catch(err => reject(err)); }); };
3. 后端与APIM适配
后端不需要修改授权验证逻辑,仅需确保Azure APIM配置满足:
- HTTP接口路由(含SignalR协商请求
/signalr/negotiate)正常透传至后端服务 - WebSocket专属路由透传至后端SignalR端点,同时完整保留query参数、请求头中的授权信息
部署后可通过浏览器控制台Network标签验证:首先会发起HTTP请求到remoteServiceBaseUrl对应的地址完成协商授权,之后发起WebSocket连接到专属后缀的地址,连接成功即可正常使用。
内容的提问来源于stack exchange,提问作者omnomnom
相关产品推荐
相关产品推荐

