Flutter Web端signalr_core longPolling连接自动关闭如何解决
Flutter Web 端 SignalR 长轮询连接自动关闭修复方案
问题背景
Flutter Web 环境下 WebSocket 传输模式无法正常工作,因此 Web 端切换为 longPolling 作为 SignalR 传输方式,但搭建的连接会无预期自动关闭,原有连接构建代码如下:
HubConnectionBuilder() .withUrl(url, HttpConnectionOptions(client: httpClient, accessTokenFactory: getToken, transport: kIsWeb ? HttpTransportType.longPolling : HttpTransportType.webSockets)) .build();
修复配置项
按以下顺序排查调整配置即可解决自动断连问题:
- 显式设置长轮询间隔,不要使用默认值。默认轮询间隔通常在15秒以上,很容易被Nginx、CDN等中间节点的默认10秒空闲超时规则判定为无效连接掐断,在
HttpConnectionOptions中新增pollingInterval参数,值设为5秒即可适配绝大多数代理场景:HttpConnectionOptions( client: httpClient, accessTokenFactory: getToken, transport: kIsWeb ? HttpTransportType.longPolling : HttpTransportType.webSockets, // 新增轮询间隔配置 pollingInterval: const Duration(seconds: 5), ) - 对齐客户端与服务端的超时配置,新增
serverTimeout参数,值需要大于轮询间隔的2倍,避免正常轮询周期被客户端判定为超时主动断连,比如轮询间隔设为5秒时,超时时间设为30秒即可:HttpConnectionOptions( client: httpClient, accessTokenFactory: getToken, transport: kIsWeb ? HttpTransportType.longPolling : HttpTransportType.webSockets, pollingInterval: const Duration(seconds: 5), // 新增服务端超时配置 serverTimeout: const Duration(seconds: 30), ) - 检查自定义
httpClient的逻辑,确保所有长轮询的后续请求都和首次协商请求一致,携带正确的认证Token、Cookie信息。高频踩坑点是自定义客户端的拦截器只匹配了首次建连请求,后续轮询请求没带认证信息,被服务端以未授权为由断开连接。 - 长轮询模式下不要开启
skipNegotiation参数。只有WebSocket传输支持跳过协商流程,长轮询必须通过协商请求拿到服务端分配的连接ID,才能维持后续轮询会话,跳过协商会导致服务端无法识别轮询请求,直接断开连接。 - 如果你在服务端前部署了Nginx、CDN等反向代理,需要同步修改代理的空闲连接超时配置,保证超时阈值大于你设置的轮询间隔,避免代理层主动掐断连接。
- 如果使用的是第三方SignalR客户端包(比如signalr_core),先升级到最新稳定版本,旧版本存在Web端长轮询请求头丢失、轮询逻辑异常的已知bug,升级后即可解决。
内容的提问来源于stack exchange,提问作者Kokila
相关产品推荐
相关产品推荐

