SignalR连接无法关闭?(IIS 10 + ASP.NET MVC环境)
WebSocket连接异常排查与修复方案
一、EndRequest状态的WebSocket连接是否正常?
这是异常的挂起请求,并非WebSocket连接的正常表现。正常情况下,IIS中活跃的WebSocket连接会标记为WebSocket类型请求,状态不会停留在EndRequest。这类状态的请求说明WebSocket处理逻辑没有正确完成生命周期,处于未释放的挂起状态,会持续占用服务器线程、句柄、内存等资源,积累到一定程度就会引发服务器崩溃。
结合你提到的堆栈winWebSocketHandler+<>c__DisplayClass5_0+<b__0>d;0 [AWAIT#0],可以确定问题出在WebSocket异步处理环节——请求卡在了异步等待步骤,没有触发正确的连接收尾流程。
二、如何处理并提前关闭这类挂起连接?
1. 修复WebSocket核心逻辑漏洞
- 给异步操作添加超时控制:在WebSocket的接收、发送逻辑中,使用
CancellationTokenSource设置合理超时(比如30秒),避免无限等待。示例代码片段:using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); try { await webSocket.ReceiveAsync(buffer, cts.Token); } catch (OperationCanceledException) { await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Timeout", CancellationToken.None); } - 完善异常分支的资源清理:无论连接正常断开还是异常中断,都要确保调用
WebSocket.CloseAsync()或WebSocket.Abort()释放连接资源,避免内存泄漏。 - 检查第三方库问题:如果使用了封装的WebSocket框架,确认是否存在版本bug,必要时升级到稳定版或替换为更可靠的实现。
2. 配置IIS层面的限制与超时
- 设置WebSocket保持连接超时:在IIS站点的WebSocket功能配置中,将“保持连接超时”设为60秒以内,让IIS主动回收空闲连接。
- 调整应用池参数:在应用池高级设置中,设置请求超时(推荐120秒),开启快速失败保护,并根据服务器配置合理设置最大工作进程数,防止单个进程资源耗尽。
- 限制并发连接:在站点高级设置中配置最大并发连接数,避免过多挂起请求压垮服务器。
3. 主动清理挂起连接
- 应用内添加定时检测:实现一个后台任务,定期扫描所有WebSocket连接状态,对超过阈值的空闲/异常连接主动关闭。
- 应急回收应用池:使用
appcmd命令临时清理所有挂起请求(仅作应急,需配合根源修复):appcmd.exe recycle apppool /apppool.name:"你的应用池名称"
4. 负载均衡层优化
- 配置负载均衡超时:在负载均衡器上设置WebSocket连接的空闲超时(比如60秒),主动断开长期无交互的连接,避免无效请求转发到后端。
- 启用会话保持:如果业务需要,开启负载均衡的WebSocket会话保持,确保同一连接始终路由到同一服务器,避免跨节点的连接异常。
内容的提问来源于stack exchange,提问作者perfect_element
相关产品推荐
相关产品推荐

