SignalR部署IIS后WebSocket 1006错误排查与解决求助
问题概述
出现SignalR报错:WebSocket closed with status code: 1006 (no reason given) called while in state Connected,本地调试时连接正常,部署到IIS后连接建立1秒左右就断开。已排查代理、VPN问题,IIS已启用WebSockets,服务器日志无异常记录。
客户端(Angular)实现代码
this.hubConnection = new HubConnectionBuilder() .withUrl(environment.appUrl + '/api/hub/weatherforecast', { skipNegotiation: true, transport: signalR.HttpTransportType.WebSockets, logMessageContent: true }) .configureLogging(signalR.LogLevel.Trace) .build(); this.hubConnection .start() .then(() => console.log('SignalR connection started')) .catch(err => console.log('Error while starting SignalR connection: ' + err)); this.hubConnection.onclose = (error) => { console.log('SignalR connection closing'); console.log(error); window.location.reload(); };
服务器端配置代码
app.UseEndpoints(endpoints => { endpoints.MapHub<DeviceHub>("/api/hub/weatherforecast"); });
浏览器控制台日志
[2024-03-04T11:16:23.996Z] Debug: Starting HubConnection.
[2024-03-04T11:16:23.996Z] Debug: Starting connection with transfer format 'Text'.
[2024-03-04T11:16:23.997Z] Trace: (WebSockets transport) Connecting.
SignalR connection refreshing
SignalR listeners added successfully
[2024-03-04T11:16:24.015Z] Information: WebSocket connected to ws://192.168.1.100:31234/api/hub/weatherforecast.
[2024-03-04T11:16:24.015Z] Debug: The HttpConnection connected successfully.
[2024-03-04T11:16:24.015Z] Debug: Sending handshake request.
[2024-03-04T11:16:24.016Z] Trace: (WebSockets transport) sending data. String data of length 32. Content: '{"protocol":"json","version":1}'.
[2024-03-04T11:16:24.016Z] Information: Using HubProtocol 'json'.
[2024-03-04T11:16:24.029Z] Trace: (WebSockets transport) data received. String data of length 3. Content: '{}'.
[2024-03-04T11:16:24.030Z] Debug: Server handshake complete.
[2024-03-04T11:16:24.030Z] Trace: (WebSockets transport) sending data. String data of length 11. Content: '{"type":6}'.
[2024-03-04T11:16:24.030Z] Debug: HubConnection connected successfully.
SignalR connection started
[2024-03-04T11:16:26.111Z] Trace: (WebSockets transport) socket closed.
[2024-03-04T11:16:26.111Z] Debug: HttpConnection.stopConnection(Error: WebSocket closed with status code: 1006 (no reason given).) called while in state Connected.
[2024-03-04T11:16:26.112Z] Error: Connection disconnected with error 'Error: WebSocket closed with status code: 1006 (no reason given).'.
[2024-03-04T11:16:26.112Z] Debug: HubConnection.connectionClosed(Error: WebSocket closed with status code: 1006 (no reason given).) called while in state Connected.
服务器日志
04-03-2024 | 16:28:10.802 | INFO | Request starting HTTP/1.1 GET http://192.168.1.100:31234/api/hub/weatherforecast - -
04-03-2024 | 16:28:10.802 | DEBUG | The request path does not match the path filter
04-03-2024 | 16:28:10.802 | DEBUG | 1 candidate(s) found for the request path '/api/hub/weatherforecast'
04-03-2024 | 16:28:10.802 | DEBUG | Request matched endpoint '/api/hub/weatherforecast'
04-03-2024 | 16:28:10.802 | DEBUG | The request has an origin header: 'http://localhost:5000'.
04-03-2024 | 16:28:10.802 | INFO | CORS policy execution successful.
04-03-2024 | 16:28:10.802 | INFO | Executing endpoint '/api/hub/weatherforecast'
04-03-2024 | 16:28:10.802 | DEBUG | New connection Fx_ljUj6zb5j2umX9pJeCQ created.
04-03-2024 | 16:28:10.802 | DEBUG | Establishing new connection.
04-03-2024 | 16:28:10.817 | DEBUG | OnConnectedAsync started.
04-03-2024 | 16:28:10.817 | DEBUG | Socket opened using Sub-Protocol: '(null)'.
04-03-2024 | 16:28:10.830 | DEBUG | Found protocol implementation for requested protocol: json.
04-03-2024 | 16:28:10.830 | DEBUG | Completed connection handshake. Using HubProtocol 'json'.
排查方向及解决方案
- 检查IIS应用程序池设置:
- 确认应用程序池的
.NET CLR版本与项目目标框架匹配(如项目用.NET 6,池内选择No Managed Code或对应版本)。 - 调整
进程模型中的闲置超时,若设置过短会导致连接被回收,建议调大或设为0禁用闲置超时。
- 确认应用程序池的
- 关闭IIS快速失败保护:
应用程序池的快速失败保护触发时会终止进程,导致连接断开。临时关闭该功能测试,若恢复正常再排查频繁崩溃原因。 - 验证WebSocket的IIS配置:
- 确认站点级WebSocket无特殊限制,且服务器绑定协议(HTTP/HTTPS)与客户端连接协议一致(服务器用HTTPS时,客户端需用WSS而非WS)。
- 移除强制跳过协商配置:
客户端设置skipNegotiation: true可能在IIS环境下不兼容,注释该配置及指定transport的代码,让SignalR自动选择传输方式测试。 - 检查服务器防火墙/安全软件:
确保服务器防火墙放行WebSocket端口(默认80/443,自定义端口31234需单独放行),排查是否有安全软件拦截连接。 - 启用IIS详细错误日志:
在站点日志设置中开启详细字段,查看是否有隐藏的请求拒绝原因。 - 排查
OnConnectedAsync逻辑:
服务器端DeviceHub的OnConnectedAsync方法若有未完成的异步操作或未捕获异常,会导致连接异常断开,添加日志或调试该方法。 - 确认SignalR版本兼容性:
客户端Angular的SignalR包版本需与服务器端版本完全一致,版本不匹配会导致握手后连接异常。
内容的提问来源于stack exchange,提问作者RelativeLayouter

