在特定网络上重定向 OkHttp3 请求

Redirect OkHttp3 requests on a specific network

当我在 WiFi 上超时时,我尝试重定向移动连接上的流量。为此,我使用 NetworkRequest 并请求 TRANSPORT_CELLULAR,它给了我一个 Network 对象,我尝试将它与 OkHttp3 一起使用。

我的初始(未绑定到网络)OkHttp 实例是这样实例化的:

OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder()
    .connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS)
    .readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
    .sslSocketFactory(mSSLSocketFactory, new MyTrustManager())
    .dns(mNetworkDns)
    .hostnameVerifier(new MyHostnameVerifier());

使用我的 SSLSocketFactory createSocket 方法:

  @Override
  public Socket createSocket(Socket socket, String s, int i, boolean flag) throws IOException {
    if (mNetwork != null) {
      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        Socket bindedSocket = mNetwork.getSocketFactory().createSocket(s, i);
        return mFactory.createSocket(bindedSocket, s, i, flag);
      }
    }
    return mFactory.createSocket(socket, s, i, flag);
  }

和这样的 Dns 查找:

  @Override
  public List<InetAddress> lookup(String hostname) throws UnknownHostException {
    if (mNetwork != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      List<InetAddress> addresses = Arrays.asList(mNetwork.getAllByName(hostname));
      Log.i("NetworkDns", "List : " + addresses);
      return addresses;
    }
    return SYSTEM.lookup(hostname);
  }

如果没有设置网络,它正在工作。 但是如果我在某一时刻将一个网络对象传递给我的 SSLSocketFactory 和我的 DNS,我只会超时:D/OkHttp: <-- HTTP FAILED: java.net.SocketTimeoutException: connect timed out

我在 createSocket 和 lookup 方法中放置了几个断点,它们似乎可以正常工作,使用它们应该使用的网络对象。 知道我该如何解决或解决这个问题吗?

好的,看来 SSLSocketFactory 中的 createSocket 不应该这样使用。我终于通过将绑定到我的网络的标准 SocketFactory 添加到我的 OkHttpClient 实例来使其工作。

OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder()
    .connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS)
    .readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
    .socketFactory(myNetwork.getSocketFactory())
    .sslSocketFactory(mSSLSocketFactory, new MyTrustManager())
    .dns(mNetworkDns)
    .hostnameVerifier(new MyHostnameVerifier());

最后,我没有覆盖 SSLSocketFactory 中的 createSocket 方法。这样套接字就绑定到我的网络,甚至是 SSL 的。