return Service.START_STICKY;\r
}else if (HEART_ALARM.equals(paramIntent.getAction())) {\r
if (this.mKeepAlive != null) {\r
- this.mKeepAlive.onHeartAlarm(this.connection, this.runtime);\r
+\r
+ if (connection.isServerConnected()&& runtime.isServerProtocolConnected()) {\r
+ this.mKeepAlive.onHeartAlarm(this.connection, this.runtime);\r
+ }else{\r
+ ICLogger.i("check 发送心跳包时,如果发现服务器没有响应,或者socket连接,则重新尝试连接服务器!");\r
+ connection.disconnectServer();\r
+ this.startConnectionRetryTimer();\r
+ }\r
setHeartAlarm();\r
if (Config.LOG_TOFILE) FileOutputUtil.fileOutput(runtime.getCacheDir(), "alarmCycle", "HEART_ALARM alarmCycle " );\r
return Service.START_STICKY;\r
\r
private Timer mTimer_retry_connect=null;\r
\r
+ private static int retry_connect_count=0; //当前重试次数\r
+ private static int retry_connect_max_times=6; //最大重试次数 6次 , 即只重试2分钟,下一次重试将在下一个心跳包时进行。\r
+ private static int retry_cocnnect_cycle=20; //重试间隔20秒\r
private void log(String msg) {\r
ICLogger.log(TAG,msg);\r
}\r
//如果开始进行连接重\r
// {\r
// 试,证明网络断开的,那么KeepAlive也需要重连(心跳包)\r
-\r
+ retry_connect_count=0;\r
KeepAlive.isConnected = false;\r
if (mTimer_retry_connect != null) {\r
mTimer_retry_connect.schedule(new TimerTask() {\r
public void ReConnectToServer(){\r
\r
if (SimSignalUtil.checkNet(runtime.getContextProxy().context) ) {\r
- String ip=runtime.getDnsUtil().getServerIP_ByDNSCache(runtime.getHost());\r
- if (null != ip && !ip.equals(runtime.getSrvIP())) {\r
- runtime.setSrvIP(ip);\r
- }\r
- this.connection.connect(this.runtime.getSrvIP(), this.runtime.getPort());\r
-\r
- //里面如果连接成功 connectionOpen 会先发送 AP00 登录包 和发送AP03 心跳包 ,都成功则停止重试\r
- if (connection.isServerConnected() && KeepAlive.isConnected) {\r
+ //里面如果连接成功 connectionOpen 会先发送 AP00 登录包 和发送AP03 心跳包 ,\r
+ // isServerConnected 成功则停止重试, KeepAlive会检测AP03心跳包的成功与否。此处只管socket连接是否成功\r
+ if (connection.isServerConnected()) {\r
+ ICLogger.i("retry 如果连接成功则停止重试!");\r
stopConnectionRetryTimer();\r
+ }else {\r
+ if (retry_connect_count >= retry_connect_max_times) {\r
+\r
+ ICLogger.i("retry " + retry_connect_count + " 次 >= " + retry_connect_max_times + " ,停止重试!等待下一次心跳再重试!");\r
+ stopConnectionRetryTimer();\r
+\r
+ } else {\r
+ retry_connect_count++;\r
+ String ip = runtime.getDnsUtil().getServerIP_ByDNSCache(runtime.getHost());\r
+ if (null != ip && !ip.equals(runtime.getSrvIP())) {\r
+ runtime.setSrvIP(ip);\r
+ }\r
+ ICLogger.i("retry 第" + retry_connect_count + " 次 , 连接服务器!");\r
+ this.connection.connect(this.runtime.getSrvIP(), this.runtime.getPort());\r
+\r
+ }\r
}\r
}else{\r
//没有网络就不用重新尝试连接网络了。网络连接后再重新尝试联网\r
+ ICLogger.i("retry 没有网络就不用重新尝试连接网络了。网络连接后再重新尝试联网!");\r
stopConnectionRetryTimer();\r
}\r
}\r
import com.enqualcomm.support.utils.NetworkObservable;\r
import com.enqualcomm.support.utils.ServiceUtil;\r
import com.enqualcomm.support.bean.Runtime;\r
+import com.enqualcomm.support.utils.SimSignalUtil;\r
\r
+import java.util.Timer;\r
+import java.util.TimerTask;\r
import java.util.concurrent.TimeUnit;\r
\r
import rx.Observable;\r
private int totalAdjustTimes;\r
\r
private int whichTimeAdjust;\r
- \r
- static {\r
- \r
+\r
+//服务器收到AP03 会返回BP03,如果PB03 规定时间没收到,则认为发送心跳失败,需要重发,\r
+ private boolean is_heartBeat_send_success=false;\r
+ //如果重试5次还没有连接上,则需要重新断开连接重新连接服务器。\r
+ private int hearBeatResendCount=0;\r
+ private int MaxHeartbeatResendTime=6;\r
+ //每次retry发送心跳的间隔为20秒\r
+ private int heartBeatRetryTimeout=5;\r
+ //监测 心跳服务器响应的timer\r
+ private Timer mTimer_check_server_response=null;\r
+\r
+\r
+ public void startResponseCheckTimer(){\r
+ //联网再重试连接服务器\r
+ if (SimSignalUtil.checkNet(mRuntime.getContextProxy().context) ) {\r
+ stopResponseCheckTimer();\r
+ if (mTimer_check_server_response == null) {\r
+ mTimer_check_server_response = new Timer();\r
+ }\r
+\r
+ //开始检测重新计数\r
+ hearBeatResendCount=0;\r
+ //如果开始进行连接重\r
+ // {\r
+ // 试,证明网络断开的,那么KeepAlive也需要重连(心跳包)\r
+\r
+ if (mTimer_check_server_response != null) {\r
+ mTimer_check_server_response.schedule(new TimerTask() {\r
+ @Override\r
+ public void run() {\r
+ checkSrvResponse();\r
+ }\r
+ }, 0, heartBeatRetryTimeout*1000); //每5秒重试一次\r
+ }\r
+ }\r
}\r
\r
+\r
+ public void checkSrvResponse(){\r
+\r
+ if (SimSignalUtil.checkNet(mRuntime.getContextProxy().context) ) {\r
+\r
+\r
+ //如果收到服务器响应BP03,则停止重试,否则 继续发送AP03 心跳包,且继续检查响应\r
+ if (this.is_heartBeat_send_success ) {\r
+ ICLogger.i("checkSrvResponse 成功,停止检测!");\r
+ stopResponseCheckTimer();\r
+ }else{\r
+ //如果重试次数大于等于 最大重试次数,则停止重试,等下次心跳时间再行尝试。\r
+ if (hearBeatResendCount >= MaxHeartbeatResendTime){\r
+ ICLogger.i("checkSrvResponse "+hearBeatResendCount+"次 >= "+MaxHeartbeatResendTime+" , 则停止重试,等下次心跳时间再行尝试!");\r
+ stopResponseCheckTimer();\r
+ }else {\r
+ //重新发送AP03心跳包\r
+ ICLogger.i("checkSrvResponse 失败,第" + hearBeatResendCount + "次,重新发送AP03心跳包!");\r
+ //心跳开始发送的时候,先重置response检测标志\r
+ is_heartBeat_send_success = false;\r
+ hearBeatResendCount++;\r
+ connection.send(protocolAPIHelper.genStringMessage("heart", protocolAPIHelper.AP03(mRuntime)));\r
+ }\r
+ }\r
+\r
+ }else{\r
+ //没有网络就不用重新尝试连接网络了。网络连接后再重新尝试联网\r
+ ICLogger.i("checkSrvResponse stop , 没有网络就不用重新尝试检测服务器响应和重新发送心跳包了!");\r
+\r
+ stopResponseCheckTimer();\r
+ }\r
+ }\r
+\r
+ public void stopResponseCheckTimer(){\r
+ if (mTimer_check_server_response !=null){\r
+ mTimer_check_server_response.cancel();\r
+ mTimer_check_server_response = null;\r
+ }\r
+ }\r
+\r
+\r
\r
public void onAlarmClock(Connection paramConnection, Runtime paramRuntime) {\r
\r
stringBuilder.append(this.first);\r
ICLogger.i(stringBuilder.toString());\r
if (param1Integer.intValue() > 0) {\r
+ //返回值大于0 证明是网络连接成功,开始重连服务器\r
if (this.first) {\r
this.first = false;\r
return;\r
}\r
+ ICLogger.i("数据网络连接成功,重新连接网络。");\r
CoreService.getInstance().ReConnectToServer();\r
} \r
}\r
});\r
IntentFilter intentFilter = new IntentFilter();\r
- intentFilter.addAction("android.intent.action.ACTION_SHUTDOWN_MOREINFO");\r
+ intentFilter.addAction("android.intent.action.ACTION_SHUTDOWN");\r
this.mShutDownReceiver = new ShutDownReceiver();\r
this.mContext.registerReceiver(this.mShutDownReceiver, intentFilter);\r
}\r
\r
// if (isConnected)\r
//如果KeepAlive被关闭说明网络有问题,因此开启重试联网机制\r
+ stopResponseCheckTimer();\r
CoreService.getInstance().startConnectionRetryTimer();\r
connectionError = true;\r
isConnected = false;\r
// CoreService.needLocateInAfterHeartBeat=true;\r
return false;\r
}\r
- \r
+\r
public boolean onConnectionOpen(Connection paramConnection, Runtime paramRuntime) {\r
\r
StringBuilder stringBuilder = new StringBuilder();\r
// if (!connectionError) {\r
connectionError = false;\r
\r
-\r
//发送登录包\r
Observable.timer(500L, TimeUnit.MILLISECONDS).subscribe(new Action1<Long>() {\r
public void call(Long param1Long) {\r
\r
}\r
});\r
- //发送心跳包\r
+ //心跳开始发送的时候,先重置response检测标志\r
+ is_heartBeat_send_success=false;\r
+ //发送心跳包\r
Observable.timer(5500L, TimeUnit.MILLISECONDS).subscribe(new Action1<Long>() {\r
public void call(Long param1Long) {\r
+ //这时重新连接服务器才进行的连接,理论上close已经设置false,此次可以认为协议定然断开,所以设置为false作为双重保险。\r
+ mRuntime.setServerProtocolConnected(false);\r
connection.send(protocolAPIHelper.genStringMessage("heart",protocolAPIHelper.AP03(paramRuntime)));\r
+ //发送完心跳后,开始检查服务器响应\r
+ startResponseCheckTimer();\r
}\r
});\r
\r
- isConnected = true;\r
+ isConnected = true;\r
this.firstReConnected = true;\r
this.idleTimeMillis = SystemClock.elapsedRealtime();\r
\r
\r
public void onHeartAlarm(NettyConnection paramNettyConnection, Runtime paramRuntime) {\r
ICLogger.i("onHeartAlarm");\r
-// UpdateHeartBeatTimeout();\r
-// if (this.reCycleTimes == 0 && this.currentReConnectInterval != 11){\r
-// paramNettyConnection.send(protocolAPIHelper.genStringMessage("AP00",protocolAPIHelper.AP00(paramRuntime)));\r
- paramNettyConnection.send(protocolAPIHelper.genStringMessage("heart",protocolAPIHelper.AP03(paramRuntime)));\r
\r
- // }\r
+ stopResponseCheckTimer();\r
+ //心跳开始发送的时候,先重置response检测标志\r
+ is_heartBeat_send_success=false;\r
+\r
+ //这个是正常心跳包,暂时不能认为服务器连接时失败的,所以正常发送检测。\r
+ //发送心跳包\r
+ connection.send(protocolAPIHelper.genStringMessage("heart",protocolAPIHelper.AP03(paramRuntime)));\r
+ //发送完心跳后,开始检查服务器响应\r
+ startResponseCheckTimer();\r
+\r
\r
}\r
\r
}else if ("BP03".equals(paramStringMessage.cmd())){\r
// 收到心跳才认为是已经连接了服务器\r
paramRuntime.setServerProtocolConnected(true);\r
+// isConnected = true;\r
+ is_heartBeat_send_success=true;\r
+//广播服务器连接成功的消息\r
paramRuntime.getContextProxy().sendBroadcast(isConnected);\r
LauncherCtrl.getInstance(this.mContext).setStatusBarIcon("server_connected", STATUS_BAR_STATE_SERVER_CONNECTED_ON);\r
// Deliver.triggerSendThread(); //链接上就尝试清除 buffer中的数据\r
CoreService.getInstance().stopConnectionRetryTimer();\r
-\r
if (CoreService.needLocateInAfterHeartBeat==true){\r
//第一次启动或者系统Close后重连的时候,重置LocationCycle\r
CoreService.needLocateInAfterHeartBeat=false;\r
class ShutDownReceiver extends BroadcastReceiver {\r
public void onReceive(Context param1Context, Intent param1Intent) {\r
boolean bool = param1Intent.getBooleanExtra("reboot", false);\r
- if (KeepAlive.this.mRuntime.getBatteryLow() && !KeepAlive.this.mRuntime.getBatterychanging() && !bool && !KeepAlive.this.mRuntime.isShutdown()){\r
+ ICLogger.i("Shutdown Received! reboot="+bool);\r
+ if (KeepAlive.this.mRuntime.getBatteryLow() && !KeepAlive.this.mRuntime.getBatterychanging() && !bool && !KeepAlive.this.mRuntime.isShutdown()/*不是服务器让关闭的*/){\r
\r
KeepAlive.this.mRuntime.setAlarmType(false,KeepAlive.this.mRuntime.getBatteryLow(),false,false);\r
KeepAlive.this.connection.send(protocolAPIHelper.genStringMessage("AP10",protocolAPIHelper.AP10(KeepAlive.this.mRuntime)));\r
+\r
+ ICLogger.i("Shutdown Received! send AP10 !");\r
+\r
}\r
\r
}\r