Angular 6集成SignalR报错"WebSocket is not in the OPEN state"求助
解决SignalR "WebSocket is not in the OPEN state" 错误
首先,最可能的问题是你在SignalR连接完全建立成功之前,就尝试订阅Hub的事件了。hubConnection.start()是异步操作,返回的是Promise,如果你在组件ngOnInit里先调用startConnection(),紧接着就调用addTransferChartDataListener(),这时候连接还处于正在建立的状态,还没进入OPEN状态,自然会抛出这个错误。
解决方案1:保证连接成功后再订阅事件
你可以修改服务里的startConnection方法,要么把订阅事件的逻辑放到start()的成功回调里,要么让startConnection返回Promise,在组件里等待连接完成后再执行监听逻辑。
修改后的服务代码示例:
public startConnection = () => { let loggedInuser = this.user.getUserEmail(); let accessToken ="some token"; var options = { transport: signalR.HttpTransportType.WebSockets, logging: signalR.LogLevel.Trace, accessTokenFactory: () => accessToken }; this.hubConnection = new signalR.HubConnectionBuilder() .withUrl(this.url + loggedInuser , options) .build(); this.hubConnection.serverTimeoutInMilliseconds = 9999999999999; // 返回Promise,让组件可以等待连接完成 return this.hubConnection .start() .then(() => { console.log('Connection started'); // 在这里直接调用监听方法,确保连接已处于OPEN状态 this.addTransferChartDataListener(); }) .catch(err => { console.log('url: ' + this.url + loggedInuser) console.log('Error while starting connection: ', err) }) }
然后在组件的ngOnInit里这样调用:
ngOnInit() { this.signalRService.startConnection(); // 因为监听逻辑已经放到服务的成功回调里了,这里不需要额外调用 }
其他需要排查的细节
- URL参数拼接是否正确:你当前的url是
baseurl+'&users=',如果baseurl本身没有包含?(比如baseurl是/notificationHub而不是/notificationHub?xxx),那参数拼接会格式错误,应该改成baseurl + '?users='。URL格式错误会直接导致连接失败,间接引发WebSocket状态异常。 - WebSocket传输是否被服务器支持:虽然你指定了
WebSockets传输,但如果服务器端没启用WebSocket,或者反向代理(比如Nginx)没配置WebSocket支持,SignalR会尝试降级到其他传输,但可能会导致连接状态不稳定。可以尝试去掉transport配置,让SignalR自动选择最佳传输方式。 - 添加重连逻辑:为了避免连接断开后无法恢复,建议加上重连处理:
this.hubConnection.onclose(() => { console.log('Connection closed, reconnecting...'); setTimeout(() => this.startConnection(), 5000); });
总结
核心问题是异步操作的顺序错误,必须确保SignalR连接成功建立(start()的Promise执行完成)后,再去订阅Hub的事件。另外检查URL格式和服务器端的WebSocket配置,这些都可能导致连接无法正常初始化,进而触发状态错误。
内容的提问来源于stack exchange,提问作者Anish K Pillai
相关产品推荐
相关产品推荐

