SignalR WebSockets本地正常但Windows Server 2016服务器连接失败
我正在为使用SignalR 2.4.2的ASP.NET 4.8 Framework应用配置Web Sockets通信协议。该应用在Windows 10 Pro系统的Visual Studio 2019本地环境运行完全正常,但部署到非Azure的Windows 2016服务器后出现连接错误。
报错信息
Chrome 85浏览器报错
signalr?v=igzza46L1gfiUBzl96WDUmuI9_CUHV_qqd0Kd-fDr8A1:1 WebSocket connection to 'wss://someServer.org/signalr/connect?transport=webSockets&clientProtocol=2.1&connectionToken=...&connectionData=%5B%7B%22name%22%3A%22myhub%22%7D%5D&tid=0' failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET
后续JS栈报错:
No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization. at Object.error (signalr?vv=...:1) at g (signalr?vv=...:1) at v (signalr?vv=...:1) at h.transportFailed (signalr?vv=...:1) at signalr?vv=...:1 at WebSocket.e.socket.e.socket.onclose (signalr?vv=...:1)
Firefox完整日志
SignalR: Client subscribed to hub 'myhub'. SignalR: Negotiating with '/signalr/negotiate?clientProtocol=2.1&connectionToken=...&connectionData=%5B%7B%22name%22%3A%22myhub%22%7D%5D'. SignalR: webSockets transport starting. SignalR: Connecting to websocket endpoint 'wss://myServer.org/signalr/connect?transport=webSockets&clientProtocol=2.1&connectionToken=...%3D%3D&connectionData=%5B%7B%22name%22%3A%22myhub%22%7D%5D&tid=8' Firefox can’t establish a connection to the server at wss://myServer.org/signalr/connect?transport=webSockets&clientProtocol=2.1&connectionToken=...&connectionData=%5B%7B%22name%22%3A%22myhub%22%7D%5D&tid=8. SignalR: Websocket closed. SignalR: Closing the Websocket. SignalR: webSockets transport failed to connect. Attempting to fall back. SignalR: No fallback transports were selected. SignalR: Stopping connection. SignalR: Fired ajax abort async = true.
已验证信息
服务器上访问https://myserver.org/signalr/negotiate返回的SignalR配置正常,明确标记TryWebSockets: true:
Url "/signalr" ConnectionToken "..." ConnectionId "..." KeepAliveTimeout 20 DisconnectTimeout 30 ConnectionTimeout 110 TryWebSockets true ProtocolVersion "1.2" TransportConnectTimeout 5 LongPollDelay 0
已尝试的解决方案
- 按照官方文档完成Windows Server 2016的WebSockets功能安装
- 客户端调用代码仅指定webSockets作为传输协议:
$.connection.hub.logging = true; $.connection.hub.start({ transport: ['webSockets'] }) .done(function () { // ... }).fail(e => { console.log(e); });
- 已禁用Visual Studio的BrowserLink功能
- 移除
Global.asax.cs中的Application_PreSendRequestHeaders方法,问题仍存在
关键更新
通过RDP登录服务器本地访问页面时,Web Sockets协议可以正常工作。
问题原因与解决方案
根据你补充的「服务器本地访问WebSocket正常、外部访问失败」的特征,问题出在服务器和客户端之间的中间网络节点,和应用本身、IIS配置无关,按优先级逐一排查即可:
1. 检查服务器端防火墙配置
Windows Server 2016默认防火墙可能没有放行WebSocket所需的通信规则,注意WebSocket是基于HTTP/HTTPS端口的升级协议,需要确认:
- 你站点用的80/443端口是否允许外部TCP入站
- 防火墙是否启用了「应用层过滤」规则,主动拦截了WebSocket的
Upgrade请求头
可以临时关闭服务器防火墙测试,如果恢复正常,新增对应端口的入站规则即可。
2. 检查站点前的反向代理/负载均衡配置
如果你的服务器前面部署了Nginx、Apache、CDN、WAF等反向代理设备,这类设备默认很多不会处理WebSocket升级请求,需要在代理配置中添加WebSocket相关的请求头透传规则,以Nginx为例需要加上:
proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_http_version 1.1;
如果是云服务商的WAF/负载均衡,需要在控制台开启WebSocket支持选项,很多云产品默认是关闭的。
3. 检查运营商网络限制
部分运营商的企业宽带、专线会主动拦截非标准HTTP请求,你可以尝试用4G移动热点访问站点测试,如果移动网络可以正常连接WebSocket,联系运营商解除对应限制即可。
内容的提问来源于stack exchange,提问作者Alex

