| 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(); | 
|     } | 
|   | 
| } |