初始化
配置通道服务
必须在应用启动时(Application的onCreate方法中)初始化通道服务配置,所有进程都需要执行。try {
// 参考脚手架demo从配置文件获取
Map ipStrategy = new HashMap();
int env = Constants.RELEASE;
int pubkey = SpdyProtocol.PUBKEY_PSEQ_EMAS;
String appkey = "";
String appsecret =""
String accsHost = "";
String emasAccsTag = AccsClientConfig.DEFAULT_CONFIGTAG;
// initNetwork(mApplication, ipStrategy, accsHost, accsPort)
final AccsClientConfig clientConfig = new AccsClientConfig.Builder()
.setAppKey(appkey)
.setAppSecret(appsecret)
.setInappHost(emasHost)
.setInappPubKey(pubkey)
.setChannelHost(emasHost)
.setChannelPubKey(pubkey)
.setTag(emasAccsTag)
.setConfigEnv(env)
.build();
ACCSClient.init(mApplication, clientConfig);
} catch (AccsException e) {
ALog.w(TAG, "initDefaultAccsConfig", e);
}
appkey、appsecret、emasHost可以参考脚手架Demo工程如何获取。
emasAccsTag一般情况下可以使用AccsClientConfig.DEFAULT_CONFIGTAG,也可以自定义,后续获取accs实例时需要。
注意
如果emasHost即accs的服务地址带有端口或者有定制IP逻辑,需要做一些特殊网络设置。
特殊网络设置
参考脚手架demo代码,当accs服务地址为accs.server.com:port这种格式时,accsHost为accs.server.com,accsPort为port,需要特殊网络设置。
如果配置的有定制的IP策略,也需要特殊网络设置,在初始化通道服务配置之前调用,实现如下:private static void initNetwork(Context context, final Map ipStrategy, final String accsHost, final String accsPort) {
if ((ipStrategy == null || ipStrategy.isEmpty()) && TextUtils.isEmpty(accsPort)) {
return;
}
SessionCenter.init(context);
final IStrategyInstance instance = StrategyCenter.getInstance();
StrategyCenter.setInstance(new IStrategyInstance() {
private String mACCSDomainIp;
@Override
public void initialize(Context context) {
instance.initialize(context);
}
@Override
public void switchEnv() {
instance.switchEnv();
}
@Override
public void saveData() {
instance.saveData();
}
@Override
public String getFormalizeUrl(String rawUrlString) {
return instance.getFormalizeUrl(rawUrlString);
}
@Override
public List getConnStrategyListByHost(String host) {
List list = null;
if (ipStrategy != null && !ipStrategy.isEmpty()) {
String strategy = ipStrategy.get(host);
if (TextUtils.isEmpty(strategy)) {
return instance.getConnStrategyListByHost(host);
}
final String[] ipPort = strategy.split(":");
list = new ArrayList();
IConnStrategy connStrategy = new IConnStrategy() {
@Override
public String getIp() {
return ipPort[0];
}
@Override
public int getIpType() {
return 0;
}
@Override
public int getIpSource() {
return 0;
}
@Override
public int getPort() {
return Integer.parseInt(ipPort[1]);
}
@Override
public ConnProtocol getProtocol() {
return ConnProtocol.valueOf("http2", "0rtt", "emas", false);
}
@Override
public int getConnectionTimeout() {
return 10000;
}
@Override
public int getReadTimeout() {
return 10000;
}
@Override
public int getRetryTimes() {
return 1;
}
@Override
public int getHeartbeat() {
return 0;
}
};
list.add(connStrategy);
} else if (accsHost != null && accsHost.equals(host) && !TextUtils.isEmpty(accsPort)) {
if (TextUtils.isEmpty(mACCSDomainIp)) {
try {
InetAddress ip = InetAddress.getByName(accsHost);
mACCSDomainIp = ip.getHostAddress();
} catch (UnknownHostException e) {
}
}
list = new ArrayList();
IConnStrategy connStrategy = new IConnStrategy() {
@Override
public String getIp() {
return mACCSDomainIp;
}
@Override
public int getIpType() {
return 0;
}
@Override
public int getIpSource() {
return 0;
}
@Override
public int getPort() {
return Integer.parseInt(accsPort);
}
@Override
public ConnProtocol getProtocol() {
return ConnProtocol.valueOf("http2", "0rtt", "emas", false);
}
@Override
public int getConnectionTimeout() {
return 10000;
}
@Override
public int getReadTimeout() {
return 10000;
}
@Override
public int getRetryTimes() {
return 1;
}
@Override
public int getHeartbeat() {
return 0;
}
};
list.add(connStrategy);
} else {
return instance.getConnStrategyListByHost(host);
}
return list;
}
@Override
public String getSchemeByHost(String host) {
return instance.getSchemeByHost(host);
}
@Override
public String getSchemeByHost(String host, String dftScheme) {
return instance.getSchemeByHost(host, dftScheme);
}
@Override
public String getCNameByHost(String host) {
return instance.getCNameByHost(host);
}
@Override
public String getClientIp() {
return instance.getClientIp();
}
@Override
public void notifyConnEvent(String host, IConnStrategy connStrategy, ConnEvent connEvent) {
instance.notifyConnEvent(host, connStrategy, connEvent);
}
@Override
public String getUnitByHost(String s) {
return null;
}
@Override
public void forceRefreshStrategy(String host) {
instance.forceRefreshStrategy(host);
}
@Override
public void registerListener(IStrategyListener listener) {
instance.registerListener(listener);
}
@Override
public void unregisterListener(IStrategyListener listener) {
instance.unregisterListener(listener);
}
});
}
通道服务建立连接
初始化配置后,就可以建立连接了,这一步可以异步执行,避免造成主线程卡顿。//建议异步进行建立连接
new Thread() {
@Override
public void run() {
try {
ACCSClient.getAccsClient(AccsClientConfig.DEFAULT_CONFIGTAG).bindApp(mChannelID, mAppReceiver);
} catch (AccsException e) {
ALog.w(TAG, "initDefaultAccs", e);
}
}
}.start();
mChannelID为渠道ID,可以根据需要自己定义
mAppReceiver声明如下:public final static String TEST_SERVICE_ID = "emas-test";
private final static Map SERVICES = new HashMap() {
private static final long serialVersionUID = 2527336442338823324L;
{
put(TEST_SERVICE_ID, "com.taobao.demo.accs.TestAccsService");
}
};
private IAppReceiver mAppReceiver = new IAppReceiver() {
private String TAG = "mAppReceiver";
@Override
public void onBindApp(int errorCode) {
ALog.i(TAG, "onBindApp", "errorCode", errorCode);
}
@Override
public void onUnbindApp(int errorCode) {
ALog.i(TAG, "onUnbindApp", "errorCode", errorCode);
}
@Override
public void onBindUser(String userId, int errorCode) {
ALog.i(TAG, "onBindUser", "errorCode", errorCode);
}
@Override
public void onUnbindUser(int errorCode) {
ALog.i(TAG, "onUnbindUser", "errorCode", errorCode);
}
@Override
public void onSendData(String dataId, int errorCode) {
ALog.i(TAG, "onSendData");
}
@Override
public void onData(String userId, String dataId, byte[] data) {
ALog.i(TAG, "onData");
}
@Override
public String getService(String serviceId) {
String service = SERVICES.get(serviceId);
return service;
}
@Override
public Map getAllServices() {
return SERVICES;
}
};
当连接建立成功之后,通过onBindApp回调通知业务方。
其中 TEST_SERVICE_ID 是为了示例定义的服务器端业务服务标识
com.taobao.demo.accs.TestAccsService 是客户端接收此业务服务数据的本地服务,继承自TaoBaseService,定义如下/**
* 第一个accs默认实例, 消息回调类
*/
public class TestAccsService extends TaoBaseService {
private static final String TAG = "TestAccsService";
/**
* bindService回调
*
* @param serviceId 服务ID
* @param errorCode 错误码=200为成功,其他失败
* @param extraInfo
*/
@Override
public void onBind(String serviceId, int errorCode, ExtraInfo extraInfo) {
ALog.d(TAG, "onBind", "serviceId", serviceId, "errorCode", errorCode);
}
/**
* unbindService回调
*
* @param serviceId 服务ID
* @param errorCode 错误码=200为成功,其他失败
* @param extraInfo
*/
@Override
public void onUnbind(String serviceId, int errorCode, ExtraInfo extraInfo) {
ALog.d(TAG, "onUnbind", "serviceId", serviceId, "errorCode", errorCode);
}
/**
* sendData回调
*
* @param serviceId 服务ID
* @param dataId 数据ID
* @param errorCode 错误码=200为成功,其他失败
* @param extraInfo
*/
@Override
public void onSendData(String serviceId, String dataId, int errorCode, ExtraInfo extraInfo) {
ALog.d(TAG, "onSendData", "serviceId", serviceId, "dataId", dataId, "errorCode", errorCode);
}
/**
* sendRequest回调
*
* @param serviceId 服务ID
* @param dataId 数据ID
* @param errorCode 错误码=200为成功,其他失败
* @param bytes
* @param extraInfo
*/
@Override
public void onResponse(String serviceId, String dataId, int errorCode, byte[] bytes, ExtraInfo extraInfo) {
}
/**
* 下行数据回调
*
* @param serviceId 服务ID
* @param userId 用户ID
* @param dataId 数据ID
* @param bytes
* @param extraInfo
*/
@Override
public void onData(String serviceId, String userId, String dataId, byte[] bytes, ExtraInfo extraInfo) {
}
/**
* 连接成功状态回调
*
* @param conninfo
*/
@Override
public void onConnected(ConnectInfo conninfo) {
ALog.d(TAG, "onConnected", "host", conninfo.host, "isInapp", conninfo.isInapp);
}
/**
* 连接失败状态回调
*
* @param conninfo
*/
@Override
public void onDisconnected(ConnectInfo conninfo) {
ALog.e(TAG, "onDisconnected", "host", conninfo.host, "isInapp", conninfo.isInapp,
"errorCode", conninfo.errorCode, "errorDetail", conninfo.errordetail);
}
}
记得在manifest进行声明