Flutter 中自定义DNS解析的实现

为了提升Flutter中网络请求的速度,集成了阿里云的DNS解析服务,在官方示例中未提供基于Dio的实现, 因此经过调研后,尝试基于Dio进行自定义扩展实现,最开始做的时候,首先想到的是使用自定义Dio的拦截器进行实现,经过一系列的调研后,发现Dio中拦截器的执行顺序是在DNS解析之后,所以即使在拦截器中实现了DNS解析,也毫无意义,因此采用了自定义Proxy代理的方式进行实现。

第一步创建Proxy

class DomainHttpClientAdapter extends HttpClientAdapter {
  @override
  void close({bool force = false}) {
  }

  //需要解析的域名
  var spareHostArray = [
    "taobo",
  ];
  @override
  Future<ResponseBody> fetch(
      RequestOptions options, Stream<Uint8List>? requestStream, Future<dynamic>? cancelFuture) async {
    // 自定义 DNS 解析
    LogUtils.d("DomainHttpClientAdapter------------>fetch-->${options.uri.host}");
    Uri newUri = options.uri;
    if (spareHostArray.contains(options.uri.host)) {
      String host = options.uri.host;
      String ipAddress = await _resolveHostToIp(host);
      int port = options.uri.port;
      String scheme = options.uri.scheme;
      String newPath = '$scheme://$ipAddress:$port${options.uri.path}${options.uri.query}';
      LogUtils.d("DomainHttpClientAdapter------------>newPath->$newPath-->");
      options.baseUrl = newPath;
      options.path = "";
    }
    final HttpClient httpClient = HttpClient();
    LogUtils.d("DomainHttpClientAdapter------------>openUrl-newUri->$newUri--baseUrl->${options.baseUrl}");
    final HttpClientRequest httpRequest = await httpClient.openUrl(options.method, newUri);
    // 设置请求头
    options.headers.forEach((key, value) {
      httpRequest.headers.set(key, value);
    });

    // 写入请求体
    if (requestStream != null) {
      await requestStream.forEach(httpRequest.add);
    }

    final HttpClientResponse httpResponse = await httpRequest.close();

    // 读取响应数据
    final List<int> responseBody = await httpResponse.fold([], (List<int> a, List<int> b) => a..addAll(b));

    return ResponseBody.fromBytes(
      responseBody,
      httpResponse.statusCode,
      headers: convertHeaders(httpResponse.headers),
      statusMessage: httpResponse.reasonPhrase,
    );
  }

  // 将 HttpHeaders 转换为 Dio 需要的 headers 格式
  Map<String, List<String>> convertHeaders(HttpHeaders headers) {
    Map<String, List<String>> convertedHeaders = {};
    headers.forEach((name, values) {
      convertedHeaders[name] = values;
    });
    return convertedHeaders;
  }

///使用通道,发送消息到原生进行DNS解析
  Future<String> _resolveHostToIp(String host) async {
    try{
      
      var ip =  await ChannelManager.getInstance().sendMessage("getIpByHost",host);
      LogUtils.d("DomainHttpClientAdapter------------>_resolveHostToIp-->$ip");
      return ip;
    }catch(e){
      return host;
    }
  }
}

第二步,给Dio增加自定义代理

dio.httpClientAdapter = DomainHttpClientAdapter();

通过如上两步即可实现Flutter中自定义DNS解析,本案例只作为参考,提供一种自定义解析DNS的实现方案,具体实现,可根据自己项目进行定制实现。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值