进阶
RPC API请求
请求与响应数据均为序列化后的byte[]
WeakReference<SharkHandler> sendBytes(int cmdId,
byte[] reqData, int flag, ISendBytesCallback callback, long timeoutMillis);
参数类型 | 参数 | 说明 |
---|---|---|
int | cmdId | API命令字,参考API标识 |
byte[] | reqData | 请求包的二进制数据 |
int | flag | (1)可设置回调在哪个线程 子线程回调:SharkCommonConst.CALLBACK_RUN_ON_THREAD UI线程回调:SharkCommonConst.CALLBACK_RUN_ON_UI (2)可设置请求发起的通道 默认值(优先TCP,TCP失败走HTTP):CHANNEL_DEFAULT HTTP通道:CHANNEL_ONLY_HTTP TCP通道:CHANNEL_ONLY_TCP |
ISendBytesCallback | callback | 网络请求回调接口 |
long | timeoutMillis | 超时时间,单位毫秒,默认超时时间3分钟 |
请求与响应结构为JceStruct子类
WeakReference<SharkHandler> sendJceStruct(int cmdId,
JceStruct req, JceStruct resp, int flag, ISendJceCallback callback, long timeoutMillis);
参数类型 | 参数 | 说明 |
---|---|---|
int | cmdId | API命令字, 参考API标识 |
JceStruct | req | 请求包jce结构体 |
JceStruct | resp | 服务器回包的结构,调用者new一个对象进来即可,框架为使协议可混淆且屏蔽解包细节,需要传入此参数。若传null表示不关心回包,此时框架不去解析回包数据 |
int | flag | (1)可设置回调在哪个线程 子线程回调:SharkCommonConst.CALLBACK_RUN_ON_THREAD UI线程回调:SharkCommonConst.CALLBACK_RUN_ON_UI (2)可设置请求发起的通道 默认值(优先TCP,TCP失败走HTTP):CHANNEL_DEFAULT HTTP通道:CHANNEL_ONLY_HTTP TCP通道:CHANNEL_ONLY_TCP |
ISendJceCallback | callback | 网络请求回调接口 |
long | timeoutMillis | 超时时间,单位毫秒,默认超时时间3分钟 |
JceStruct是RPC结构体基类,通过jce文件定义,可使用相应工具生成。
调整内置shark实例参数
基础库初始化时根据指定配置文件创建了内置shark实例,如果您需要调整内置shark配置进行个性化设定,可以参照如下方法进行:
TMFBaseConfig config = new TMFBaseConfig.Builder()
.sharkConfigAdjustCallback(new ISharkConfigAdjustCallback() {
@Override
public void onAdjust(TMFSharkConfigInfo sharkConfigInfo) {
//在此调整配置信息
}
})
.build();
TMFBase.init(this, config);
说明:sharkConfigInfo请参考《SharkConfigInfo》。
TCP通道开启与关闭
内置实例设置方法
内置实例默认开启了tcp通道,如果需要关闭tcp通道可参考如下代码:
TMFBaseConfig config = new TMFBaseConfig.Builder()
.sharkConfigAdjustCallback(new ISharkConfigAdjustCallback() {
@Override
public void onAdjust(TMFSharkConfigInfo sharkConfigInfo) {
//在此调整配置信息
sharkConfigInfo.enableTcp = false; //true表示打开,false表示关闭
}
})
.build();
TMFBase.init(this, config);
非内置实例设置方法
请参考创建Shark实例
指定通道发送请求
TMF支持TCP/HTTP双通道,发送请求时可以通过flag标记指定发送通道,建议您使用默认标记SharkCommonConst.CHANNEL_DEFAULT,双通道互补提升发送效率。您也可以指定单个通道进行请求。
使用Http通道发送数据
shark.sendHttpEntity(req, SharkCommonConst.CHANNEL_ONLY_HTTP, callback, 100000);
使用tcp通道发送数据
shark.sendHttpEntity(req, SharkCommonConst.CHANNEL_ONLY_TCP, callback, 100000);
开启TCP通道IP透传
在某些特定网络环境下,您可能无法通过TCP通道获取到真实的客户端IP,IP透传功能借助HTTP通道获取到真实客户端IP后,再通过TCP通道透传给后端,具体开启方法
基础库内置shark实例开启方法:
TMFBaseConfig config = new TMFBaseConfig.Builder()
.sharkConfigAdjustCallback(new ISharkConfigAdjustCallback() {
@Override
public void onAdjust(TMFSharkConfigInfo sharkConfigInfo) {
//开启IP透传
sharkConfigInfo.ipPassThrough = true;
}
})
.build();
TMFBase.init(this, config);
非内置shark实例开启方法:
Shark shark = SharkFactory.builder(context) // 必填
.enableIpPassThrough(true) // 开启IP透传
.build();
// 关闭自动启动
shark.start(false);
开启TCP通道IPv6
Shark HTTP通道使用的是系统API, 因此双栈支持依赖系统底层API实现,无需做特殊处理。TCP通道双栈实现采用的是赛马机制,v6和v4在一定延迟规则下并发连接,优先连接成功的会被采用。由于双栈模式性能一定下降,所以默认是关闭的。如果需要开启IPv6,请参考如下步骤:
- 打开IPv6(必须)
SharkConfigInfo.supportIPv6设置为true, 内置shark实例参数调整请参考调整内置shark实例参数。
sharkConfigInfo.supportIPv6 = true
- 配置IPv6地址(必须)
IPv6地址可以与IPv4地址区分开来单独配置,一般情况下v6与v4地址是相同的,请根据您服务的实际情况进行配置。
//与IPv4相关配置保持一致
sharkConfigInfo.tcpHostIPv6 = sharkConfigInfo.tcpHost;
sharkConfigInfo.tcpPortIPv6 = sharkConfigInfo.tcpPort;
sharkConfigInfo.httpUrlIpV6 = sharkConfigInfo.httpUrl;
切换应用配置数据迁移规则
从基线1.8.0起(shark 3.x以上版本)TMF支持按照环境隔离框架数据,不同应用配置的框架数据会存储在独立的数据目录中互不影响。由于旧版Shark无法自动检测当前运行环境变化情况,需要您根据实际情况来指定数据迁移规则。具体规则如下:
- 如果您没有切换应用配置,那么需要将旧版数据统一迁移到新版数据存储结构中,MigrateType设置为MigrateAll。
- 若果您只切换了应用配置,没有切换平台(customID没有变化),那么应用数据无需保留,可以只迁移vid相关数据,MigrateType设置为MigrateVidOnly。
- 如果您切换了平台,customID和productID都发生了变化,那么无需迁移任何数据到新版,MigrateType设置为MigrateNothing。
内置Shark实例设置方法
TMFBaseConfig config = new TMFBaseConfig.Builder()
.migrateType(MigrateAll)//根据实际情况进行设置
.build();
TMFBase.init(this, config);
非内置Shark实例设置方法
请参考《 升级到1.8.1基线 》。
服务端证书绑定校验
如果您因为特殊的安全需求,需要对服务端证书做绑定校验,请参考如下说明:
移动网关HTTP通道支持两种证书绑定校验:
- 指定信任的证书文件,对证书文件进行完整校验,服务端返回的证书链中有证书校验通过,则校验通过,否则不通过。
- 设置信任证书公钥,只校验证书文件的公钥信息,服务端返回的证书链中有证书公钥可信,则校验通过,否则不通过。
SSLPinCfg.Builder
public static class Builder{
/**
* 绑定证书公钥的sha256, 只校验公钥部分,证书链中包含指定公钥则通过校验
*
* @param sha256 证书公钥sha256的base64字符串
* @return
*/
public Builder addSHA256OfPublicKey(String sha256);
/**
* 绑定放在assets中的证书文件(pem/der/crt),证书链中包含指定证书则通过校验
*
* @param assetName 证书文件的asset名字
* @return
*/
public Builder addAssetNameOfCert(String assetName);
/**
* 构建SSLPinCfg
*/
public SSLPinCfg build();
}
证书绑定校验设置示例
TMFBaseConfig config = new TMFBaseConfig.Builder()
//...
.sharkConfigAdjustCallback(new ISharkConfigAdjustCallback() {
@Override
public void onAdjust(TMFSharkConfigInfo sharkConfigInfo) {
//...
sharkConfigInfo.sslPinCfg = new SSLPinCfg.Builder()
//指定信任证书文件,文件位于assets/certs/selfsigned.cert
.addAssetNameOfCert("certs/selfsigned.cert")
//指定信任证书文件,文件位于assets/tbbank.cer
.addAssetNameOfCert("tbbank.cer")
//指定信任公钥,格式为公钥SHA256的base64字符串
.addSHA256OfPublicKey("Ye0tdZMsVzzUD8GYr4hV+2ywj8UPMT6wexK0gudQ6DQ=")
//指定信任公钥,格式为公钥SHA256的base64字符串
.addSHA256OfPublicKey("jzqM6/58ozsPRvxUzg0hzjM+GcfwhTbU/G0TCDvL7hU=")
.build();
//域名校验回调
sharkConfigInfo.hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
//根据实际情况对域名进行校验
return true;
}
};
}
})
.build();
TMFBase.init(CommonApp.get().getApplication(), config);
自定义HTTP通道URLConnection创建
移动网关HTTP通道URLConnection创建支持用户自定义,从而实现个性化配置。常见的使用场景有下面几种:
- 将HttpURLConnection实现导向国密SSL实现
- 对HttpURLConnection做个性化设置,如设置代理
IUrlStreamHandler接口
/**
* http通道,URLConnection工厂,可用于将实现导出到okhttp
*/
public interface IUrlStreamHandler {
URLConnection openConnection(URL u) throws IOException;
URLConnection openConnection(URL u, Proxy p) throws IOException;
/**
* 用特定网络创建URLConnection
*/
URLConnection openConnection(URL url, Network network) throws IOException;
/**
* 用特定网络创建URLConnection
*/
URLConnection openConnection(URL url, Network network, java.net.Proxy proxy) throws IOException;
}
代码示例
public class DefaultUrlSteamHandler implements IUrlStreamHandler {
@Override
public URLConnection openConnection(URL u) throws IOException {
return u.openConnection();
}
@Override
public URLConnection openConnection(URL u, Proxy p) throws IOException {
return u.openConnection(p);
}
@Override
public URLConnection openConnection(URL url, Network network) throws IOException {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return network.openConnection(url);
} else {
return url.openConnection();
}
}
@Override
public URLConnection openConnection(URL url, Network network, Proxy proxy) throws IOException {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return network.openConnection(url, proxy);
} else {
return url.openConnection(proxy);
}
}
}