开发者社区> 问答> 正文

HttpDnsOkHttp怎么用代码实现IP直连


HTTPS(含SNI)业务场景“IP直连”方案说明一文介绍了利用HttpDns解析获得ip后进行ip直连的通用方法。但是如果您在Android端使用的网络框架是OkHttp,通过调用OkHttp提供的自定义Dns服务接口,可以更为优雅地使用HttpDns的服务。
OkHttp是一个处理网络请求的开源项目,是Android端最火热的轻量级框架,由移动支付Square公司贡献用于替代HttpUrlConnection和Apache HttpClient。随着OkHttp的不断成熟,越来越多的Android开发者使用OkHttp作为网络框架。
OkHttp默认使用系统DNS服务InetAddress进行域名解析,但同时也暴露了自定义DNS服务的接口,通过该接口我们可以优雅地使用HttpDns。

1. 自定义DNS接口


OkHttp暴露了一个Dns接口,通过实现该接口,我们可以自定义Dns服务:

  1. [backcolor=transparent]public[backcolor=transparent] [backcolor=transparent]class[backcolor=transparent] [backcolor=transparent]OkHttpDns[backcolor=transparent] [backcolor=transparent]implements[backcolor=transparent] [backcolor=transparent]Dns[backcolor=transparent] [backcolor=transparent]{
  2. [backcolor=transparent]    [backcolor=transparent]private[backcolor=transparent] [backcolor=transparent]static[backcolor=transparent] [backcolor=transparent]final[backcolor=transparent] [backcolor=transparent]Dns[backcolor=transparent] SYSTEM [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]Dns[backcolor=transparent].[backcolor=transparent]SYSTEM[backcolor=transparent];
  3. [backcolor=transparent]    [backcolor=transparent]HttpDnsService[backcolor=transparent] httpdns[backcolor=transparent];[backcolor=transparent]//httpdns 解析服务
  4. [backcolor=transparent]    [backcolor=transparent]private[backcolor=transparent] [backcolor=transparent]static[backcolor=transparent] [backcolor=transparent]OkHttpDns[backcolor=transparent] instance [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]null[backcolor=transparent];
  5. [backcolor=transparent]    [backcolor=transparent]private[backcolor=transparent] [backcolor=transparent]OkHttpDns[backcolor=transparent]([backcolor=transparent]Context[backcolor=transparent] context[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]{
  6. [backcolor=transparent]        [backcolor=transparent]this[backcolor=transparent].[backcolor=transparent]httpdns [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]HttpDns[backcolor=transparent].[backcolor=transparent]getService[backcolor=transparent]([backcolor=transparent]context[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]"account id"[backcolor=transparent]);
  7. [backcolor=transparent]    [backcolor=transparent]}
  8. [backcolor=transparent]    [backcolor=transparent]public[backcolor=transparent] [backcolor=transparent]static[backcolor=transparent] [backcolor=transparent]OkHttpDns[backcolor=transparent] getInstance[backcolor=transparent]([backcolor=transparent]Context[backcolor=transparent] context[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]{
  9. [backcolor=transparent]        [backcolor=transparent]if[backcolor=transparent]([backcolor=transparent]instance [backcolor=transparent]==[backcolor=transparent] [backcolor=transparent]null[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]{
  10. [backcolor=transparent]            instance [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]OkHttpDns[backcolor=transparent]([backcolor=transparent]context[backcolor=transparent]);
  11. [backcolor=transparent]        [backcolor=transparent]}
  12. [backcolor=transparent]        [backcolor=transparent]return[backcolor=transparent] instance[backcolor=transparent];
  13. [backcolor=transparent]    [backcolor=transparent]}
  14. [backcolor=transparent]    [backcolor=transparent]@Override
  15. [backcolor=transparent]    [backcolor=transparent]public[backcolor=transparent] [backcolor=transparent]List[backcolor=transparent]<[backcolor=transparent]InetAddress[backcolor=transparent]>[backcolor=transparent] lookup[backcolor=transparent]([backcolor=transparent]String[backcolor=transparent] hostname[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]throws[backcolor=transparent] [backcolor=transparent]UnknownHostException[backcolor=transparent] [backcolor=transparent]{
  16. [backcolor=transparent]        [backcolor=transparent]//通过异步解析接口获取ip
  17. [backcolor=transparent]        [backcolor=transparent]String[backcolor=transparent] ip [backcolor=transparent]=[backcolor=transparent] httpdns[backcolor=transparent].[backcolor=transparent]getIpByHostAsync[backcolor=transparent]([backcolor=transparent]hostname[backcolor=transparent]);
  18. [backcolor=transparent]        [backcolor=transparent]if[backcolor=transparent]([backcolor=transparent]ip [backcolor=transparent]!=[backcolor=transparent] [backcolor=transparent]null[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]{
  19. [backcolor=transparent]            [backcolor=transparent]//如果ip不为null,直接使用该ip进行网络请求
  20. [backcolor=transparent]            [backcolor=transparent]List[backcolor=transparent]<[backcolor=transparent]InetAddress[backcolor=transparent]>[backcolor=transparent] inetAddresses [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]Arrays[backcolor=transparent].[backcolor=transparent]asList[backcolor=transparent]([backcolor=transparent]InetAddress[backcolor=transparent].[backcolor=transparent]getAllByName[backcolor=transparent]([backcolor=transparent]ip[backcolor=transparent]));
  21. [backcolor=transparent]            [backcolor=transparent]Log[backcolor=transparent].[backcolor=transparent]e[backcolor=transparent]([backcolor=transparent]"OkHttpDns"[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]"inetAddresses:"[backcolor=transparent] [backcolor=transparent]+[backcolor=transparent] inetAddresses[backcolor=transparent]);
  22. [backcolor=transparent]            [backcolor=transparent]return[backcolor=transparent] inetAddresses[backcolor=transparent];
  23. [backcolor=transparent]        [backcolor=transparent]}
  24. [backcolor=transparent]        [backcolor=transparent]//如果返回null,走系统DNS服务解析域名
  25. [backcolor=transparent]        [backcolor=transparent]return[backcolor=transparent] [backcolor=transparent]Dns[backcolor=transparent].[backcolor=transparent]SYSTEM[backcolor=transparent].[backcolor=transparent]lookup[backcolor=transparent]([backcolor=transparent]hostname[backcolor=transparent]);
  26. [backcolor=transparent]    [backcolor=transparent]}
  27. [backcolor=transparent]}


2. 创建OkHttpClient


创建OkHttpClient对象,传入OkHttpDns对象代替默认Dns服务:
  1. [backcolor=transparent]private[backcolor=transparent] [backcolor=transparent]void[backcolor=transparent] okhttpDnsRequest[backcolor=transparent]()[backcolor=transparent] [backcolor=transparent]{
  2. [backcolor=transparent]    [backcolor=transparent]OkHttpClient[backcolor=transparent] client [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]OkHttpClient[backcolor=transparent].[backcolor=transparent]Builder[backcolor=transparent]()
  3. [backcolor=transparent]    [backcolor=transparent].[backcolor=transparent]dns[backcolor=transparent]([backcolor=transparent]OkHttpDns[backcolor=transparent].[backcolor=transparent]getInstance[backcolor=transparent]([backcolor=transparent]getApplicationContext[backcolor=transparent]()))
  4. [backcolor=transparent]    [backcolor=transparent].[backcolor=transparent]build[backcolor=transparent]();
  5. [backcolor=transparent]    [backcolor=transparent]Request[backcolor=transparent] request [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]Request[backcolor=transparent].[backcolor=transparent]Builder[backcolor=transparent]()
  6. [backcolor=transparent]    [backcolor=transparent].[backcolor=transparent]url[backcolor=transparent]([backcolor=transparent]"http://www.aliyun.com"[backcolor=transparent])
  7. [backcolor=transparent]    [backcolor=transparent].[backcolor=transparent]build[backcolor=transparent]();
  8. [backcolor=transparent]    [backcolor=transparent]Response[backcolor=transparent] response [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]null[backcolor=transparent];
  9. [backcolor=transparent]    client[backcolor=transparent].[backcolor=transparent]newCall[backcolor=transparent]([backcolor=transparent]request[backcolor=transparent]).[backcolor=transparent]enqueue[backcolor=transparent]([backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]Callback[backcolor=transparent]()[backcolor=transparent] [backcolor=transparent]{
  10. [backcolor=transparent]        [backcolor=transparent]@Override
  11. [backcolor=transparent]        [backcolor=transparent]public[backcolor=transparent] [backcolor=transparent]void[backcolor=transparent] onFailure[backcolor=transparent]([backcolor=transparent]Call[backcolor=transparent] call[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]IOException[backcolor=transparent] e[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]{
  12. [backcolor=transparent]            e[backcolor=transparent].[backcolor=transparent]printStackTrace[backcolor=transparent]();
  13. [backcolor=transparent]        [backcolor=transparent]}
  14. [backcolor=transparent]        [backcolor=transparent]@Override
  15. [backcolor=transparent]        [backcolor=transparent]public[backcolor=transparent] [backcolor=transparent]void[backcolor=transparent] onResponse[backcolor=transparent]([backcolor=transparent]Call[backcolor=transparent] call[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]Response[backcolor=transparent] response[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]throws[backcolor=transparent] [backcolor=transparent]IOException[backcolor=transparent] [backcolor=transparent]{
  16. [backcolor=transparent]            [backcolor=transparent]if[backcolor=transparent] [backcolor=transparent](![backcolor=transparent]response[backcolor=transparent].[backcolor=transparent]isSuccessful[backcolor=transparent]())[backcolor=transparent] [backcolor=transparent]throw[backcolor=transparent] [backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]IOException[backcolor=transparent]([backcolor=transparent]"Unexpected code "[backcolor=transparent] [backcolor=transparent]+[backcolor=transparent] response[backcolor=transparent]);
  17. [backcolor=transparent]                [backcolor=transparent]DataInputStream[backcolor=transparent] dis [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]DataInputStream[backcolor=transparent]([backcolor=transparent]response[backcolor=transparent].[backcolor=transparent]body[backcolor=transparent]().[backcolor=transparent]byteStream[backcolor=transparent]());
  18. [backcolor=transparent]                [backcolor=transparent]int[backcolor=transparent] len[backcolor=transparent];
  19. [backcolor=transparent]                [backcolor=transparent]byte[backcolor=transparent][][backcolor=transparent] buff [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]byte[backcolor=transparent][[backcolor=transparent]4096[backcolor=transparent]];
  20. [backcolor=transparent]                [backcolor=transparent]StringBuilder[backcolor=transparent] result [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]StringBuilder[backcolor=transparent]();
  21. [backcolor=transparent]                [backcolor=transparent]while[backcolor=transparent] [backcolor=transparent](([backcolor=transparent]len [backcolor=transparent]=[backcolor=transparent] dis[backcolor=transparent].[backcolor=transparent]read[backcolor=transparent]([backcolor=transparent]buff[backcolor=transparent]))[backcolor=transparent] [backcolor=transparent]!=[backcolor=transparent] [backcolor=transparent]-[backcolor=transparent]1[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]{
  22. [backcolor=transparent]                    result[backcolor=transparent].[backcolor=transparent]append[backcolor=transparent]([backcolor=transparent]new[backcolor=transparent] [backcolor=transparent]String[backcolor=transparent]([backcolor=transparent]buff[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]0[backcolor=transparent],[backcolor=transparent] len[backcolor=transparent]));
  23. [backcolor=transparent]                [backcolor=transparent]}
  24. [backcolor=transparent]                [backcolor=transparent]Log[backcolor=transparent].[backcolor=transparent]d[backcolor=transparent]([backcolor=transparent]"OkHttpDns"[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]"Response: "[backcolor=transparent] [backcolor=transparent]+[backcolor=transparent] result[backcolor=transparent].[backcolor=transparent]toString[backcolor=transparent]());
  25. [backcolor=transparent]            [backcolor=transparent]}
  26. [backcolor=transparent]        [backcolor=transparent]});
  27. [backcolor=transparent]}

以上就是OkHttp+HttpDns实现的全部代码。

3. 总结


相比于通用方案,OkHttp+HttpDns有以下两个主要优势:
  • 实现简单,只需通过实现Dns接口即可接入HttpDns服务
  • 通用性强,该方案在HTTPS,SNI以及设置Cookie等场景均适用。规避了证书校验,域名检查等环节

展开
收起
猫饭先生 2017-10-20 11:16:56 3330 0
0 条回答
写回答
取消 提交回答
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载