WebSocket生产环境异常:Flutter安卓应用卡顿响应缓慢求助
Flutter客户端连接IIS部署的.NET WebSocket后严重卡顿的排查与解决
核心问题定位:后端无限制高频推送消息
你的后端WebSocket代码存在致命逻辑问题:Echo方法里的while循环没有任何延迟,会以最高频率持续推送版本字符串。本地环境资源充足时可能没明显卡顿,但部署到IIS后,客户端的messages流会被疯狂触发,导致StreamBuilder不断重建整个应用,直接引发严重性能问题。
修复后端代码
只需在推送后添加合理延迟(比如每分钟推送一次,版本不会频繁变更):
public class WebSocketController : ControllerBase { private const string version = "3.0.0"; private static readonly TimeSpan PushInterval = TimeSpan.FromMinutes(1); [HttpGet("/ws")] public async Task Get() { if (HttpContext.WebSockets.IsWebSocketRequest) { using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); await PushVersionPeriodically(webSocket); } else { HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest; } } private static async Task PushVersionPeriodically(WebSocket webSocket) { var versionBytes = Encoding.UTF8.GetBytes(version); while (webSocket.State == WebSocketState.Open) { await webSocket.SendAsync( new ArraySegment<byte>(versionBytes), WebSocketMessageType.Text, true, CancellationToken.None); // 添加延迟,避免高频推送 await Task.Delay(PushInterval); } await webSocket.CloseOutputAsync( WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); } }
IIS服务器配置检查
启用WebSocket协议:
- 打开Windows功能,确保
Internet Information Services > World Wide Web Services > Application Development Features > WebSocket Protocol已勾选 - 重启IIS服务
- 打开Windows功能,确保
调整连接限制:
- 打开IIS管理器,找到目标应用池,设置
队列长度(建议设为1000以上)和最大并发工作进程数(根据服务器配置调整) - 检查站点的
连接限制,确保最大并发连接数足够
- 打开IIS管理器,找到目标应用池,设置
防火墙与代理配置:
- 确认服务器防火墙开放了WebSocket使用的端口(默认80/443)
- 如果使用反向代理,确保代理服务器支持WebSocket升级请求(允许
Connection: Upgrade和Upgrade: websocket请求头)
WebSocket超时设置:
- 在IIS管理器中,站点的
配置编辑器里,找到system.webServer/webSocket,调整pingInterval和connectionTimeout,避免频繁断开重连
- 在IIS管理器中,站点的
Flutter客户端优化
你的客户端代码在连接状态变化时会反复调用runApp,导致整个应用重启,加重性能负担,同时需要对消息流做过滤:
修复客户端代码
Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); final appVersion = await getVersion(); final backoff = LinearBackoff( initial: const Duration(seconds: 1), // 初始延迟避免频繁重连 increment: const Duration(seconds: 1), maximum: const Duration(seconds: 5), ); final socket = WebSocket( Uri.parse('ws://my_api_address/ws'), backoff: backoff, ); runApp( MyApp( socket: socket, appVersion: appVersion, ), ); } class MyApp extends StatelessWidget { final WebSocket socket; final String appVersion; const MyApp({super.key, required this.socket, required this.appVersion}); @override Widget build(BuildContext context) { return StreamBuilder( stream: socket.messages.distinct(), // 过滤重复消息 builder: (context, snapshot) { if (snapshot.hasData && snapshot.data != appVersion) { return RequiredVersionAlert( appVersion: appVersion, requiredVersion: snapshot.data, ); } return const App(); }, ); } }
额外排查步骤
- 用WebSocket测试工具(如wscat)连接服务器的WebSocket端点,确认推送频率是否正常
- 在客户端添加日志,记录消息接收频率和UI重建次数,验证修复效果
- 检查IIS日志,查看是否有大量WebSocket连接错误或超时记录
内容的提问来源于stack exchange,提问作者infinitesimal
相关产品推荐
相关产品推荐

