移動調度中心在 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.openMDC(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;
}
}