移动调度中心在 10.1.68 及以上版本基线中提供支持。移动调度中心支持 原生 AAR 接入 和 组件化(Portal&Bundle)接入 两种接入方式。
前置条件
若采用原生 AAR 方式接入,需先完成 将 mPaaS 添加到您的项目中 的前提条件和后续相关步骤。
若采用组件化(Portal&Bundle)方式接入,需先完成 组件化接入流程。
添加移动调度 SDK 依赖
接入 mPaaS 支持以下两种接入方式,您可以根据实际情况进行选择。
原生 AAR 方式
参考 AAR 组件管理,通过 组件管理(AAR)在工程中安装 移动调度 组件。
组件化(Portal&Bundle)方式
在 Portal 和 Bundle 工程中通过 组件管理 安装 移动调度 组件。更多信息,请参考 接入流程。
使用移动调度 SDK
添加 AndroidManifest 配置
使用 SDK 需要在 AndroidManifest 中添加移动调度中心的 dg 和 host 信息。
<!--配置移动调度中心分组名称-->
<meta-data
android:name="amdc.dg"
android:value="${MDC_DG}" />
<!--host配置为业务的移动调度中心服务域名-->
<meta-data
android:name="amdc.host"
android:value="${IP}" />
<!--可选,用于第一次本地dns缓存被污染情况下的备选IP-->
<meta-data android:name="amdc.backup"
android:value="${IP}" />
调用移动调度中心接口
MPMDC 类提供了所有移动调度中心相关 API,调用移动调度中心接口的操作步骤如下:
mPaaS 框架初始化完成后,在
Application.onCreate
中调用init
方法初始化 DMC。void init(Context context);
示例如下:
@Override public void onCreate() { super.onCreate(); MP.init(this, MPInitParam.obtain().setCallback(new MPInitParam.MPCallback() { @Override public void onInit() { MPMDC.init(App.this); } }) ); }
获取 IP 信息。
MPHttpIp getIpsByHost(String host); // 获取对应host的IP信息 List<MPHttpIp> getAll(); // 获取所有移动调度中心的IP配置信息 class MPHttpIp { public MPHttpIpEntry[] ipEntries; // IP列表 public String host; // host public String ip; //本地IP } class MPHttpIpEntry { public static final int IP_TYPE_V4 = 4; public static final int IP_TYPE_V6 = 6; public String ip; // IP public int port; // 端口 public int ipType; // IP类型,v4/v6 }
设置 UID。移动调度中心内部会根据 UID 来区分数据,提供用户灰度功能。
MPLogger.setUserId(xxxx);
RPC 开启 MDC 功能
RPC 内部会使用移动调度中心相关配置,并提供 API。业务方基于 RPC 使用 RPC 提供的接口。业务方可以使用 mPaaS 的开关配置动态控制移动调度中心和 IPv6 的开关。
开启移动调度中心开关,RPC 使用移动调度中心配置;关闭移动调度中心开关,RPC 不使用移动调度中心配置。开关默认开启。
MPRpc.openMGDC(isOpen);
关闭 IPv6 开关,RPC 会过滤掉移动调度中心 IPv6 的 IP,只使用移动调度中心 IPv4 的 IP;开启 IPv6 开关,则 IPv6 和 IPv4 IP 均使用。开关默认关闭。
MPRpc.openIPV6(isOpen);
单独接入 MDC 示例
通过 IP 完成 Socket 建连
MPHttpIp httpIp = MPHttpIp.getIpsByHost(String host);
MPHttpIpEntry[] ipEntries = httpdnsIP.ipEntries;
String ips = new String[ipEntries.length];
for (int i = 0; i < httpdnsIPEntries.length; i++) {
ipArr[i] = httpdnsIPEntries[i].ip;
}
//使用socket建连,
//selectAddressIndex 可以根据请求失败情况自行设置index
Socket newSocket = new Socket(Proxy.NO_PROXY);
newSocket.connect(new InetSocketAddress(ips[selectAddressIndex], port));
//通过ip建连后,如果访问https,还需进行ssl建连
//ssl建连,可以参考下方ssl建连参考代码,
//httpUrlConnection和okhttp同样需要设置sslSocketFactory来解决https问题
//获取socketFactory同样可以参考下面代码,均为标准模版代码,可以结合自己项目的情况
//使用httpUrlConnection
URL url = new URL("http://ips[selectAddressIndex]/index.jsp");
//如果是https,需要设置
HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
//使用okhttp
Request request = new Request.Builder()
.get()
.url("http://ips[selectAddressIndex]/index.jsp")
.build();
OkHttpClient client = new OkHttpClient.Builder()
//如果是https,需要设置
.sslSocketFactory(sslSocketFactory).build();
Call call = client.newCall(request);
通过 SSL 建连
//获取socketFactory
SSLSocketFactory sslSocketFactory = createZSSLContext().getSocketFactory();
//ssl握手
if (sslSocketFactory != null) {
SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(socket, host, port, true);
sslSocket.setUseClientMode(true);
sslSocket.startHandshake();
Log.d(LOGTAG, "tls socket ssl handshake suc");
sslSocket.setSoTimeout(0);
return sslSocket;
}
public static final SSLContext createZSSLContext() throws NoSuchAlgorithmException, KeyManagementException {
final SSLContext sslContext = SSLContext.getInstance("TLS");
final X509KeyManager x509KeyManagers[] = {createDefaultKeyManager()};
final X509TrustManager x509TrustManagers[] = {new X509TrustManagerWrapper(createDefaultTrustManager())};
sslContext.init(x509KeyManagers, x509TrustManagers, new SecureRandom());
return sslContext;
}
public static final X509KeyManager createDefaultKeyManager() throws KeyManagementException {
try {
String defaultAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory kmf = KeyManagerFactory.getInstance(defaultAlgorithm);
kmf.init(null, null);
return findX509KeyManager(kmf.getKeyManagers());
} catch (NoSuchAlgorithmException e) {
throw new KeyManagementException(e);
} catch (UnrecoverableKeyException e) {
throw new KeyManagementException(e);
} catch (KeyStoreException e) {
throw new KeyManagementException(e);
}
}
private static final X509KeyManager findX509KeyManager(KeyManager[] kms) throws KeyManagementException {
for (KeyManager km : kms) {
if (km instanceof X509KeyManager) {
return (X509KeyManager)km;
}
}
throw new KeyManagementException("Failed to find an X509KeyManager in "+ Arrays.toString(kms));
}
public static final X509TrustManager createDefaultTrustManager() throws KeyManagementException {
try {
String defaultAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(defaultAlgorithm);
tmf.init((KeyStore)null);
return findX509TrustManager(tmf.getTrustManagers());
} catch (NoSuchAlgorithmException e) {
throw new KeyManagementException(e);
} catch (KeyStoreException e) {
throw new KeyManagementException(e);
}
}
private static final X509TrustManager findX509TrustManager(TrustManager tms[]) throws KeyManagementException {
for (TrustManager tm : tms) {
if (tm instanceof X509TrustManager) {
return (X509TrustManager) tm;
}
}
throw new KeyManagementException("Failed to find an X509TrustManager in "+Arrays.toString(tms));
}
private static final class X509TrustManagerWrapper implements X509TrustManager {
private final X509TrustManager x509TrustManager;
public X509TrustManagerWrapper(X509TrustManager x509TrustManager) {
this.x509TrustManager = x509TrustManager;
}
@Override
public final void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
x509TrustManager.checkClientTrusted(chain, authType);
}
@Override
public final void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
int size = 0;
if (chain != null) {
size = chain.length;
}
try {
x509TrustManager.checkServerTrusted(chain, authType);
} catch (Throwable e) {
if (e instanceof CertificateException) {
throw (CertificateException) e;
} else {
throw new CertificateException(e);
}
}
}
@Override
public final X509Certificate[] getAcceptedIssuers() {
X509Certificate[] acceptedIssuers = x509TrustManager.getAcceptedIssuers();
return acceptedIssuers;
}
}