You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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服务器配置检查

  1. 启用WebSocket协议:

    • 打开Windows功能,确保Internet Information Services > World Wide Web Services > Application Development Features > WebSocket Protocol已勾选
    • 重启IIS服务
  2. 调整连接限制:

    • 打开IIS管理器,找到目标应用池,设置队列长度(建议设为1000以上)和最大并发工作进程数(根据服务器配置调整)
    • 检查站点的连接限制,确保最大并发连接数足够
  3. 防火墙与代理配置:

    • 确认服务器防火墙开放了WebSocket使用的端口(默认80/443)
    • 如果使用反向代理,确保代理服务器支持WebSocket升级请求(允许Connection: Upgrade和Upgrade: websocket请求头)
  4. WebSocket超时设置:

    • 在IIS管理器中,站点的配置编辑器里,找到system.webServer/webSocket,调整pingInterval和connectionTimeout,避免频繁断开重连

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 00:57:37