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

WebSocket升级连接失败:Angular可正常连接但Flutter无法连接如何解决

问题根因分析
  • Dart的WebSocket(IOWebSocketChannel底层依赖)会自动处理WebSocket握手必需的Connection、Upgrade、Sec-WebSocket-Key、Sec-WebSocket-Version头等,手动传入这两个头会导致请求头冲突,触发后端握手校验失败
  • 后端移除.withSockJs()后,前端仍使用StompConfig.SockJS构造客户端,SockJS协议会先发HTTP协商请求,后端关闭SockJS支持后无法识别该请求,无法完成协议升级
  • Spring WebSocket默认开启Origin校验,Angular端的域名已加入白名单,但Flutter端请求的Origin不在白名单内,被后端拦截返回非101状态码
  • 若使用wss协议,测试环境的自签名、过期、域名不匹配的SSL证书会被Flutter默认拒绝,导致握手中断
  • 路径配置错误:两种实现的路径前缀一个用wss一个用https,可能存在路径拼写错误,导致请求到了非WebSocket端点
解决方案

1. 修正原生WebSocket实现代码

移除手动传入的Connection和Upgrade头,代码修改为:

var channel = IOWebSocketChannel.connect(
  Uri.parse('wss://你的实际域名/路径/mywebsockets'),
  // 如有鉴权需要,仅传入自定义头比如token即可,不要传握手相关头
  headers: {
    'Authorization': 'Bearer 你的token(如果有)'
  }
);

channel.stream.listen((event) { 
  print(event);
}, onError: (e) => print('连接错误:$e'));

2. 修正Stomp客户端配置

后端移除SockJS支持后,不要使用StompConfig.SockJS构造,改用原生WebSocket的Stomp配置,url改为wss前缀:

StompClient client = StompClient(
  config: StompConfig(
    url: 'wss://你的实际域名/路径/mywebsockets',
    // 仅传入自定义头,不要传握手相关头
    stompConnectHeaders: {
      'Authorization': 'Bearer 你的token(如果有)'
    },
    onConnect: (StompFrame connectFrame) {
      print('connected');
    }, 
    onWebSocketError: (dynamic error) => print(error.toString()),
    onStompError: (d) => print("stomp error"),
    onDisconnect: (d)=> print("disconnect"),
  )
);
client.activate();

3. 后端放开Origin校验

在Spring WebSocket配置类中修改端点配置,允许Flutter端的Origin(测试可先放开所有,生产替换为实际来源):

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/mywebsockets")
        // 放开Origin限制,生产环境替换为实际的业务域名/来源
        .setAllowedOrigins("*");
        // 已经移除了withSockJS()就不要加回去
}

4. 处理SSL证书问题(仅测试环境使用,生产禁止)

如果是测试环境自签名证书,可以临时禁用Flutter的证书校验,示例如下:

HttpClient httpClient = HttpClient()
  ..badCertificateCallback = (X509Certificate cert, String host, int port) => true;

var socket = await WebSocket.connect('wss://你的实际域名/路径/mywebsockets', customClient: httpClient);
var channel = IOWebSocketChannel(socket);

5. 验证排查

如果以上步骤仍未解决,抓包对比Angular正常请求和Flutter请求的头差异,查看后端握手返回的状态码:

  • 返回403:检查Origin配置、鉴权逻辑
  • 返回404:检查请求路径是否正确
  • 返回500:查看后端错误日志排查服务端问题

内容的提问来源于stack exchange,提问作者Rahul Repala

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:36:04