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

Flutter Android端WebSocket域名解析失败但HTTP连接正常问题

Android端Flutter WebSocket域名解析失败但实际连接可用的解决方案

问题复现

使用package:web_socket_channel实现WebSocket通信、package:http处理HTTP请求时,仅Android端出现以下异常:

SocketException: Failed host lookup: 'my_domain.fun' (OS Error: No address associated with hostname, errno = 7)

核心特征:

  • 同设备、同域名下的HTTP请求完全正常
  • Web端编译后在移动浏览器中运行无问题
  • 异常来自socket_patch.dart的_NativeSocket.lookup()方法,调用栈无前置代码上下文
  • 尝试过预发起HTTP请求缓存域名、调整编译配置,均无法解决
  • 已添加INTERNET和ACCESS_NETWORK_STATE权限,设备网络正常,浏览器可访问目标域名
  • 诡异现象:抛出异常后,WebSocket连接实际仍能正常工作

代码示例

当前初始化WebSocket的代码:

class MyClass{
// this is a class property
final WebSocketChannel channel = WebSocketChannel.connect(Uri.parse('wss://my_domain.fun'));

// constructor connects to listen to the webstream
MyClass() {
    channel.stream.listen((message) {
        print(message);
        // more things happen
    });
}
}

解决方案建议

1. 延迟WebSocket初始化时机

类属性初始化阶段处于App启动早期,可能Flutter引擎的网络服务或Android系统DNS还未完全就绪。将WebSocket的创建移到异步方法中执行:

class MyClass {
  late final WebSocketChannel channel;

  MyClass() {
    _initWebSocket();
  }

  Future<void> _initWebSocket() async {
    try {
      channel = WebSocketChannel.connect(Uri.parse('wss://my_domain.fun'));
      channel.stream.listen((message) {
        print(message);
        // 后续业务逻辑
      });
    } catch (e) {
      print('WebSocket初始化异常: $e');
      // 可添加重连逻辑
    }
  }
}

2. 手动触发DNS解析后再建立连接

利用HTTP请求能正常解析域名的特性,先通过dart:io手动解析域名,再用IP地址构建WebSocket连接:

import 'dart:io';

class MyClass {
  late final WebSocketChannel channel;

  MyClass() {
    _initWebSocket();
  }

  Future<void> _initWebSocket() async {
    try {
      final addresses = await InternetAddress.lookup('my_domain.fun');
      if (addresses.isNotEmpty) {
        final ip = addresses.first.address;
        // WSS默认端口为443,若你的服务用了其他端口需修改
        final uri = Uri.parse('wss://$ip:443');
        channel = WebSocketChannel.connect(uri);
        channel.stream.listen((message) {
          print(message);
        });
      }
    } catch (e) {
      print('DNS解析或WebSocket连接失败: $e');
    }
  }
}

3. 配置Android网络安全策略

若目标域名使用自签名证书或非公共CA,需在Android项目中添加网络安全配置:

  1. 在res/xml目录下创建network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="false">
        <domain includeSubdomains="true">my_domain.fun</domain>
    </domain-config>
</network-security-config>
  1. 在AndroidManifest.xml的application标签中引用该配置:
<application
    ...
    android:networkSecurityConfig="@xml/network_security_config">

4. 捕获并过滤特定异常

既然异常抛出后连接仍能正常工作,可直接捕获该错误并忽略,不影响业务逻辑:

class MyClass{
  final WebSocketChannel channel = WebSocketChannel.connect(Uri.parse('wss://my_domain.fun'));

  MyClass() {
    channel.stream.listen((message) {
      print(message);
    }, onError: (error) {
      // 仅忽略errno=7的域名解析异常
      if (error is SocketException && error.osError?.errorCode == 7) {
        print("WebSocket域名解析异常已忽略,连接可正常使用");
      } else {
        print("WebSocket异常: $error");
      }
    });
  }
}

内容的提问来源于stack exchange,提问作者Joshua Haglund

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:43:13