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
相关产品推荐
相关产品推荐

