Angular13与.NET Framework4.8集成Azure SignalR时连接启动报错
问题概述
正在尝试将Angular 13客户端应用与集成Azure SignalR Service的.NET Framework 4.8 API对接。目前API已解决CORS问题,Postman可成功完成协商调用,客户端使用@aspnet/signalr包(误以为是唯一支持Azure SignalR Service的客户端包),但调用connection.start()时返回错误:Cannot read properties of undefined (reading 'length')。
客户端代码
import { Injectable } from '@angular/core'; import * as signalR from '@aspnet/signalr'; @Injectable() export class SignalrService { public initializeSignalRConnection(): void { let connection = new signalR.HubConnectionBuilder() .withUrl("http://localhost:58556/signalr/dashboardhub") .configureLogging(signalR.LogLevel.Debug) .build(); connection.start() .then(() => { console.log("connection.start"); //connection.invoke("send", "Hello") }) .catch((error) => { console.log("connection start error", error); }); connection.on("send", data => { console.log(data); }); } }
报错原因与解决方案
核心问题:SignalR版本不兼容
.NET Framework 4.8中使用的是ASP.NET SignalR(传统SignalR),而你安装的@aspnet/signalr是ASP.NET Core SignalR的客户端,二者协议完全不兼容,导致客户端解析协商响应时出现length未定义的错误。
具体解决步骤
替换客户端包
卸载@aspnet/signalr,安装传统SignalR对应的npm包:npm uninstall @aspnet/signalr npm install signalr修改客户端代码适配传统SignalR
传统SignalR的客户端API与Core版本差异较大,调整代码如下:import { Injectable } from '@angular/core'; import * as signalR from 'signalr'; @Injectable() export class SignalrService { public initializeSignalRConnection(): void { // 连接到SignalR主端点 const connection = signalR.hubConnection("http://localhost:58556/signalr"); // 创建指定Hub的代理 const dashboardProxy = connection.createHubProxy('dashboardhub'); // 监听服务端推送的send事件 dashboardProxy.on('send', (data) => { console.log(data); }); // 启动连接 connection.start() .then(() => { console.log("连接成功"); // 调用服务端方法示例 // dashboardProxy.invoke("send", "Hello from Angular") }) .catch((error) => { console.log("连接失败", error); }); } }修正端点路径
传统SignalR的端点是/signalr,Hub名称通过createHubProxy指定,而非URL路径中的/dashboardhub(该格式属于ASP.NET Core SignalR)。确认服务端Azure SignalR配置
确保.NET Framework 4.8 API已正确配置Azure SignalR Service,示例配置如下:using Microsoft.Azure.SignalR; using Owin; public class Startup { public void Configuration(IAppBuilder app) { // 映射Azure SignalR app.MapAzureSignalR(typeof(Startup).FullName); // 其他Owin中间件配置 } }
内容的提问来源于stack exchange,提问作者CliffAnderson

