package com.easysocket.connection.reconnect;
|
|
import android.os.Handler;
|
import android.os.HandlerThread;
|
|
import com.easysocket.entity.SocketAddress;
|
import com.easysocket.interfaces.conn.IConnectionManager;
|
import com.easysocket.utils.LogUtil;
|
|
/**
|
* Author:Alex
|
* Date:2019/5/28
|
* Note:默认重连器
|
*/
|
public class DefaultReConnection extends AbsReconnection {
|
/**
|
* 最大连接失败次数,超过可以切换到备用的服务器地址
|
*/
|
private static final int MAX_CONNECTION_FAILED_TIMES = 10;
|
/**
|
* 连接失败的次数
|
*/
|
private int connectionFailedTimes = 0;
|
/**
|
* 重连间隔不能小于10秒,为了避免全部客户端socket在同一时间连接服务端,间隔时间需要上下浮动50%
|
*/
|
private long reconnectTimeDelay = 10 * 1000;
|
/**
|
* 重连线程
|
*/
|
private HandlerThread handlerThread;
|
/**
|
* 实现延时任务的 handler
|
*/
|
private Handler handler;
|
|
public DefaultReConnection() {
|
}
|
|
@Override
|
public synchronized void attach(IConnectionManager iConnectionManager) {
|
super.attach(iConnectionManager);
|
if (reconnectTimeDelay < connectionManager.getOptions().getConnectTimeout()) {
|
reconnectTimeDelay = connectionManager.getOptions().getConnectTimeout();
|
}
|
}
|
|
/**
|
* 重连任务
|
*/
|
private final Runnable RcConnTask = new Runnable() {
|
@Override
|
public void run() {
|
LogUtil.d("---> 执行重连");
|
if (isDetach) {
|
shutDown();
|
return;
|
}
|
// 是否可连接的
|
if (!connectionManager.isConnectViable()) {
|
LogUtil.d("当前条件不允许连接");
|
// 尝试再次重连
|
handler.postDelayed(RcConnTask, (long) (reconnectTimeDelay * (Math.random() + 0.5)));
|
return;
|
}
|
// 重连
|
connectionManager.connect();
|
}
|
};
|
|
/**
|
* 进行重连
|
*/
|
private void reconnect() {
|
if (handlerThread == null) {
|
handlerThread = new HandlerThread("re_conn");
|
handlerThread.start();
|
handler = new Handler(handlerThread.getLooper());
|
}
|
LogUtil.d("重连间隔时间-->" + reconnectTimeDelay * (Math.random() + 0.5));
|
handler.postDelayed(RcConnTask, (long) (reconnectTimeDelay * (Math.random() + 0.5)));
|
}
|
|
|
// 关闭重连线程
|
private void shutDown() {
|
if (handlerThread != null && handlerThread.isAlive()) {
|
handlerThread.quit();
|
handlerThread = null;
|
handler = null;
|
}
|
}
|
|
@Override
|
public boolean equals(Object o) {
|
// getClass返回Class类型的对象,比较它们的类型对象是否==,其实是比较它们是否为同一个Class创建的对象
|
if (o == null || getClass() != o.getClass()) return false;
|
return true;
|
}
|
|
@Override
|
public void onSocketConnSuccess(SocketAddress socketAddress) {
|
// 连接成功关闭重连线程
|
shutDown();
|
}
|
|
@Override
|
public void onSocketConnFail(SocketAddress socketAddress, boolean isNeedReconnect) {
|
// 不需要重连,则关闭重连线程
|
if (!isNeedReconnect) {
|
shutDown();
|
return;
|
}
|
connectionFailedTimes++;
|
|
// 如果大于最大连接次数并且有备用host,则轮流切换两个host
|
if (connectionFailedTimes > MAX_CONNECTION_FAILED_TIMES && socketAddress.getBackupAddress() != null) {
|
connectionFailedTimes = 0; // 归零
|
SocketAddress backupAddress = socketAddress.getBackupAddress();
|
SocketAddress nowAddress = new SocketAddress(socketAddress.getIp(), socketAddress.getPort());
|
backupAddress.setBackupAddress(nowAddress);
|
if (connectionManager.isConnectViable()) {
|
connectionManager.switchHost(backupAddress);
|
// 切换主机地址,重新连接
|
reconnect();
|
}
|
} else {
|
reconnect();
|
}
|
|
}
|
|
@Override
|
public void onSocketDisconnect(SocketAddress socketAddress, boolean isNeedReconnect) {
|
// 是否需要重连
|
if (!isNeedReconnect) {
|
shutDown();
|
return;
|
}
|
reconnect();
|
}
|
|
@Override
|
public boolean isReconning() {
|
return handlerThread != null && handlerThread.isAlive();
|
}
|
|
}
|