From: snickersun Date: Thu, 5 Mar 2020 05:28:59 +0000 (+0800) Subject: 添加心跳检测机制, X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=6e5b4ea951a0109cf3c3c04e6541aef61efb053e;p=protocol_srv.git 添加心跳检测机制, 1、发送心跳包5秒检测一次服务器响应, 2、检测到响应停止检测,没检测则重发一次心跳包,继续检测, 3、6次没检测到则停止检测。 添加服务器socket连接重试机制, 1、每次心跳都检测服务器是否正常(包括socket连接和心跳包响应)任何一个有问题,都重新连接服务器 2、每20秒重新连接一次,尝试6次,如果成功则提示在检测,如果6次还是失败,则停止检测,直到下一次心跳包的检测。 编译最新版本:V369 --- diff --git a/app/release/ICSer_V367_2003022337_release.apk b/app/release/ICSer_V367_2003022337_release.apk deleted file mode 100644 index 1e5ef020..00000000 Binary files a/app/release/ICSer_V367_2003022337_release.apk and /dev/null differ diff --git a/app/release/ICSer_V369_2003051322_release.apk b/app/release/ICSer_V369_2003051322_release.apk new file mode 100644 index 00000000..c9270f0d Binary files /dev/null and b/app/release/ICSer_V369_2003051322_release.apk differ diff --git a/app/src/main/java/com/enqualcomm/support/CoreService.java b/app/src/main/java/com/enqualcomm/support/CoreService.java index abf3ce89..4283fcbc 100644 --- a/app/src/main/java/com/enqualcomm/support/CoreService.java +++ b/app/src/main/java/com/enqualcomm/support/CoreService.java @@ -675,7 +675,14 @@ public class CoreService extends Service { return Service.START_STICKY; }else if (HEART_ALARM.equals(paramIntent.getAction())) { if (this.mKeepAlive != null) { - this.mKeepAlive.onHeartAlarm(this.connection, this.runtime); + + if (connection.isServerConnected()&& runtime.isServerProtocolConnected()) { + this.mKeepAlive.onHeartAlarm(this.connection, this.runtime); + }else{ + ICLogger.i("check 发送心跳包时,如果发现服务器没有响应,或者socket连接,则重新尝试连接服务器!"); + connection.disconnectServer(); + this.startConnectionRetryTimer(); + } setHeartAlarm(); if (Config.LOG_TOFILE) FileOutputUtil.fileOutput(runtime.getCacheDir(), "alarmCycle", "HEART_ALARM alarmCycle " ); return Service.START_STICKY; @@ -832,6 +839,9 @@ public class CoreService extends Service { private Timer mTimer_retry_connect=null; + private static int retry_connect_count=0; //当前重试次数 + private static int retry_connect_max_times=6; //最大重试次数 6次 , 即只重试2分钟,下一次重试将在下一个心跳包时进行。 + private static int retry_cocnnect_cycle=20; //重试间隔20秒 private void log(String msg) { ICLogger.log(TAG,msg); } @@ -850,7 +860,7 @@ public class CoreService extends Service { //如果开始进行连接重 // { // 试,证明网络断开的,那么KeepAlive也需要重连(心跳包) - + retry_connect_count=0; KeepAlive.isConnected = false; if (mTimer_retry_connect != null) { mTimer_retry_connect.schedule(new TimerTask() { @@ -867,18 +877,31 @@ public class CoreService extends Service { public void ReConnectToServer(){ if (SimSignalUtil.checkNet(runtime.getContextProxy().context) ) { - String ip=runtime.getDnsUtil().getServerIP_ByDNSCache(runtime.getHost()); - if (null != ip && !ip.equals(runtime.getSrvIP())) { - runtime.setSrvIP(ip); - } - this.connection.connect(this.runtime.getSrvIP(), this.runtime.getPort()); - - //里面如果连接成功 connectionOpen 会先发送 AP00 登录包 和发送AP03 心跳包 ,都成功则停止重试 - if (connection.isServerConnected() && KeepAlive.isConnected) { + //里面如果连接成功 connectionOpen 会先发送 AP00 登录包 和发送AP03 心跳包 , + // isServerConnected 成功则停止重试, KeepAlive会检测AP03心跳包的成功与否。此处只管socket连接是否成功 + if (connection.isServerConnected()) { + ICLogger.i("retry 如果连接成功则停止重试!"); stopConnectionRetryTimer(); + }else { + if (retry_connect_count >= retry_connect_max_times) { + + ICLogger.i("retry " + retry_connect_count + " 次 >= " + retry_connect_max_times + " ,停止重试!等待下一次心跳再重试!"); + stopConnectionRetryTimer(); + + } else { + retry_connect_count++; + String ip = runtime.getDnsUtil().getServerIP_ByDNSCache(runtime.getHost()); + if (null != ip && !ip.equals(runtime.getSrvIP())) { + runtime.setSrvIP(ip); + } + ICLogger.i("retry 第" + retry_connect_count + " 次 , 连接服务器!"); + this.connection.connect(this.runtime.getSrvIP(), this.runtime.getPort()); + + } } }else{ //没有网络就不用重新尝试连接网络了。网络连接后再重新尝试联网 + ICLogger.i("retry 没有网络就不用重新尝试连接网络了。网络连接后再重新尝试联网!"); stopConnectionRetryTimer(); } } diff --git a/app/src/main/java/com/enqualcomm/support/MainActivity.java b/app/src/main/java/com/enqualcomm/support/MainActivity.java index a6537e8f..eefe2252 100644 --- a/app/src/main/java/com/enqualcomm/support/MainActivity.java +++ b/app/src/main/java/com/enqualcomm/support/MainActivity.java @@ -15,6 +15,7 @@ import android.widget.TextView; import android.widget.ToggleButton; import com.enqualcomm.support.R; +import com.enqualcomm.support.adapter.protocolAPIHelper; import com.enqualcomm.support.utils.DeviceInfoUtil; import com.enqualcomm.support.utils.SimSignalUtil; import com.ic.jni.ICJniUtils; @@ -23,6 +24,10 @@ import com.enqualcomm.support.utils.ICLogger; import java.util.Timer; import java.util.TimerTask; +import java.util.concurrent.TimeUnit; + +import rx.Observable; +import rx.functions.Action1; public class MainActivity extends AppCompatActivity { TextView tv; @@ -133,7 +138,13 @@ public class MainActivity extends AppCompatActivity { case R.id.btnConnect: //进行连接Socket:这里使用的是,在本地上开启了一个服务器。 stopService(new Intent(MainActivity.this,CoreService.class));// protocol service - startService(new Intent(MainActivity.this,CoreService.class));// protocol service + + //delay 5秒再重启 + Observable.timer(5000L, TimeUnit.MILLISECONDS).subscribe(new Action1() { + public void call(Long param1Long) { + startService(new Intent(MainActivity.this,CoreService.class));// protocol service + } + }); break; diff --git a/app/src/main/java/com/enqualcomm/support/service/Deliver.java b/app/src/main/java/com/enqualcomm/support/service/Deliver.java index b979ca98..c7f0db54 100644 --- a/app/src/main/java/com/enqualcomm/support/service/Deliver.java +++ b/app/src/main/java/com/enqualcomm/support/service/Deliver.java @@ -165,7 +165,7 @@ public class Deliver extends AbstractConnectionService { //如果信号不好,把msg放回去 ret=false; } else { - if (connection.isServerConnected() == false || !KeepAlive.isConnected) { + if (connection.isServerConnected() == false || !mRuntime.isServerProtocolConnected()) { ret=false; } } @@ -276,7 +276,7 @@ public static void sendLocationMSG( String Msg){ ServiceUtil.offerQueue(protocolAPIHelper.genStringMessage("queue",Msg)); triggerSendThread(); }else { - if (connection.isServerConnected() && KeepAlive.isConnected) { + if (checkNetwork()) { ICLogger.i(" first send " + Msg); connection.send(protocolAPIHelper.genStringMessage("queue",Msg)); } else { @@ -300,7 +300,7 @@ public static void sendLocationMSG( String Msg){ } public static PowerManager.WakeLock WakeLockForGetWifiList(Runtime paramRuntime) { - PowerManager.WakeLock wakeLock = ((PowerManager)(paramRuntime.getContextProxy()).context.getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, RECEIVE_WAKE_LOCKTAG); + PowerManager.WakeLock wakeLock = ((PowerManager)(paramRuntime.getContextProxy()).context.getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Deliver.class.getSimpleName()); wakeLock.acquire(120000L); return wakeLock; } @@ -321,7 +321,7 @@ public static void sendLocationMSG( String Msg){ } public PowerManager.WakeLock getWakeLock() { - PowerManager.WakeLock wakeLock = ((PowerManager)(this.mRuntime.getContextProxy()).context.getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, RECEIVE_WAKE_LOCKTAG); + PowerManager.WakeLock wakeLock = ((PowerManager)(this.mRuntime.getContextProxy()).context.getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Deliver.class.getSimpleName()); wakeLock.acquire(40000L); return wakeLock; } diff --git a/app/src/main/java/com/enqualcomm/support/service/KeepAlive.java b/app/src/main/java/com/enqualcomm/support/service/KeepAlive.java index a22aac25..8df80066 100644 --- a/app/src/main/java/com/enqualcomm/support/service/KeepAlive.java +++ b/app/src/main/java/com/enqualcomm/support/service/KeepAlive.java @@ -21,7 +21,10 @@ import com.enqualcomm.support.utils.NettyConnection; import com.enqualcomm.support.utils.NetworkObservable; import com.enqualcomm.support.utils.ServiceUtil; import com.enqualcomm.support.bean.Runtime; +import com.enqualcomm.support.utils.SimSignalUtil; +import java.util.Timer; +import java.util.TimerTask; import java.util.concurrent.TimeUnit; import rx.Observable; @@ -76,11 +79,84 @@ public class KeepAlive extends AbstractConnectionService { private int totalAdjustTimes; private int whichTimeAdjust; - - static { - + +//服务器收到AP03 会返回BP03,如果PB03 规定时间没收到,则认为发送心跳失败,需要重发, + private boolean is_heartBeat_send_success=false; + //如果重试5次还没有连接上,则需要重新断开连接重新连接服务器。 + private int hearBeatResendCount=0; + private int MaxHeartbeatResendTime=6; + //每次retry发送心跳的间隔为20秒 + private int heartBeatRetryTimeout=5; + //监测 心跳服务器响应的timer + private Timer mTimer_check_server_response=null; + + + public void startResponseCheckTimer(){ + //联网再重试连接服务器 + if (SimSignalUtil.checkNet(mRuntime.getContextProxy().context) ) { + stopResponseCheckTimer(); + if (mTimer_check_server_response == null) { + mTimer_check_server_response = new Timer(); + } + + //开始检测重新计数 + hearBeatResendCount=0; + //如果开始进行连接重 + // { + // 试,证明网络断开的,那么KeepAlive也需要重连(心跳包) + + if (mTimer_check_server_response != null) { + mTimer_check_server_response.schedule(new TimerTask() { + @Override + public void run() { + checkSrvResponse(); + } + }, 0, heartBeatRetryTimeout*1000); //每5秒重试一次 + } + } } + + public void checkSrvResponse(){ + + if (SimSignalUtil.checkNet(mRuntime.getContextProxy().context) ) { + + + //如果收到服务器响应BP03,则停止重试,否则 继续发送AP03 心跳包,且继续检查响应 + if (this.is_heartBeat_send_success ) { + ICLogger.i("checkSrvResponse 成功,停止检测!"); + stopResponseCheckTimer(); + }else{ + //如果重试次数大于等于 最大重试次数,则停止重试,等下次心跳时间再行尝试。 + if (hearBeatResendCount >= MaxHeartbeatResendTime){ + ICLogger.i("checkSrvResponse "+hearBeatResendCount+"次 >= "+MaxHeartbeatResendTime+" , 则停止重试,等下次心跳时间再行尝试!"); + stopResponseCheckTimer(); + }else { + //重新发送AP03心跳包 + ICLogger.i("checkSrvResponse 失败,第" + hearBeatResendCount + "次,重新发送AP03心跳包!"); + //心跳开始发送的时候,先重置response检测标志 + is_heartBeat_send_success = false; + hearBeatResendCount++; + connection.send(protocolAPIHelper.genStringMessage("heart", protocolAPIHelper.AP03(mRuntime))); + } + } + + }else{ + //没有网络就不用重新尝试连接网络了。网络连接后再重新尝试联网 + ICLogger.i("checkSrvResponse stop , 没有网络就不用重新尝试检测服务器响应和重新发送心跳包了!"); + + stopResponseCheckTimer(); + } + } + + public void stopResponseCheckTimer(){ + if (mTimer_check_server_response !=null){ + mTimer_check_server_response.cancel(); + mTimer_check_server_response = null; + } + } + + public void onAlarmClock(Connection paramConnection, Runtime paramRuntime) { @@ -119,16 +195,18 @@ public class KeepAlive extends AbstractConnectionService { stringBuilder.append(this.first); ICLogger.i(stringBuilder.toString()); if (param1Integer.intValue() > 0) { + //返回值大于0 证明是网络连接成功,开始重连服务器 if (this.first) { this.first = false; return; } + ICLogger.i("数据网络连接成功,重新连接网络。"); CoreService.getInstance().ReConnectToServer(); } } }); IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction("android.intent.action.ACTION_SHUTDOWN_MOREINFO"); + intentFilter.addAction("android.intent.action.ACTION_SHUTDOWN"); this.mShutDownReceiver = new ShutDownReceiver(); this.mContext.registerReceiver(this.mShutDownReceiver, intentFilter); } @@ -137,6 +215,7 @@ public class KeepAlive extends AbstractConnectionService { // if (isConnected) //如果KeepAlive被关闭说明网络有问题,因此开启重试联网机制 + stopResponseCheckTimer(); CoreService.getInstance().startConnectionRetryTimer(); connectionError = true; isConnected = false; @@ -151,7 +230,7 @@ public class KeepAlive extends AbstractConnectionService { // CoreService.needLocateInAfterHeartBeat=true; return false; } - + public boolean onConnectionOpen(Connection paramConnection, Runtime paramRuntime) { StringBuilder stringBuilder = new StringBuilder(); @@ -164,7 +243,6 @@ public class KeepAlive extends AbstractConnectionService { // if (!connectionError) { connectionError = false; - //发送登录包 Observable.timer(500L, TimeUnit.MILLISECONDS).subscribe(new Action1() { public void call(Long param1Long) { @@ -172,14 +250,20 @@ public class KeepAlive extends AbstractConnectionService { } }); - //发送心跳包 + //心跳开始发送的时候,先重置response检测标志 + is_heartBeat_send_success=false; + //发送心跳包 Observable.timer(5500L, TimeUnit.MILLISECONDS).subscribe(new Action1() { public void call(Long param1Long) { + //这时重新连接服务器才进行的连接,理论上close已经设置false,此次可以认为协议定然断开,所以设置为false作为双重保险。 + mRuntime.setServerProtocolConnected(false); connection.send(protocolAPIHelper.genStringMessage("heart",protocolAPIHelper.AP03(paramRuntime))); + //发送完心跳后,开始检查服务器响应 + startResponseCheckTimer(); } }); - isConnected = true; + isConnected = true; this.firstReConnected = true; this.idleTimeMillis = SystemClock.elapsedRealtime(); @@ -195,12 +279,17 @@ public class KeepAlive extends AbstractConnectionService { public void onHeartAlarm(NettyConnection paramNettyConnection, Runtime paramRuntime) { ICLogger.i("onHeartAlarm"); -// UpdateHeartBeatTimeout(); -// if (this.reCycleTimes == 0 && this.currentReConnectInterval != 11){ -// paramNettyConnection.send(protocolAPIHelper.genStringMessage("AP00",protocolAPIHelper.AP00(paramRuntime))); - paramNettyConnection.send(protocolAPIHelper.genStringMessage("heart",protocolAPIHelper.AP03(paramRuntime))); - // } + stopResponseCheckTimer(); + //心跳开始发送的时候,先重置response检测标志 + is_heartBeat_send_success=false; + + //这个是正常心跳包,暂时不能认为服务器连接时失败的,所以正常发送检测。 + //发送心跳包 + connection.send(protocolAPIHelper.genStringMessage("heart",protocolAPIHelper.AP03(paramRuntime))); + //发送完心跳后,开始检查服务器响应 + startResponseCheckTimer(); + } @@ -212,11 +301,13 @@ public class KeepAlive extends AbstractConnectionService { }else if ("BP03".equals(paramStringMessage.cmd())){ // 收到心跳才认为是已经连接了服务器 paramRuntime.setServerProtocolConnected(true); +// isConnected = true; + is_heartBeat_send_success=true; +//广播服务器连接成功的消息 paramRuntime.getContextProxy().sendBroadcast(isConnected); LauncherCtrl.getInstance(this.mContext).setStatusBarIcon("server_connected", STATUS_BAR_STATE_SERVER_CONNECTED_ON); // Deliver.triggerSendThread(); //链接上就尝试清除 buffer中的数据 CoreService.getInstance().stopConnectionRetryTimer(); - if (CoreService.needLocateInAfterHeartBeat==true){ //第一次启动或者系统Close后重连的时候,重置LocationCycle CoreService.needLocateInAfterHeartBeat=false; @@ -235,10 +326,14 @@ public class KeepAlive extends AbstractConnectionService { class ShutDownReceiver extends BroadcastReceiver { public void onReceive(Context param1Context, Intent param1Intent) { boolean bool = param1Intent.getBooleanExtra("reboot", false); - if (KeepAlive.this.mRuntime.getBatteryLow() && !KeepAlive.this.mRuntime.getBatterychanging() && !bool && !KeepAlive.this.mRuntime.isShutdown()){ + ICLogger.i("Shutdown Received! reboot="+bool); + if (KeepAlive.this.mRuntime.getBatteryLow() && !KeepAlive.this.mRuntime.getBatterychanging() && !bool && !KeepAlive.this.mRuntime.isShutdown()/*不是服务器让关闭的*/){ KeepAlive.this.mRuntime.setAlarmType(false,KeepAlive.this.mRuntime.getBatteryLow(),false,false); KeepAlive.this.connection.send(protocolAPIHelper.genStringMessage("AP10",protocolAPIHelper.AP10(KeepAlive.this.mRuntime))); + + ICLogger.i("Shutdown Received! send AP10 !"); + } } diff --git a/app/src/main/java/com/enqualcomm/support/utils/DeviceInfoUtil.java b/app/src/main/java/com/enqualcomm/support/utils/DeviceInfoUtil.java index 70dedfd8..87dc469c 100644 --- a/app/src/main/java/com/enqualcomm/support/utils/DeviceInfoUtil.java +++ b/app/src/main/java/com/enqualcomm/support/utils/DeviceInfoUtil.java @@ -10,6 +10,7 @@ import android.os.Build; import android.provider.Settings; import android.telephony.TelephonyManager; +import com.enqualcomm.support.CoreService; import com.enqualcomm.support.bean.StepCount; import com.enqualcomm.support.bean.Runtime; import com.enqualcomm.support.service.KeepAlive; @@ -194,7 +195,7 @@ public class DeviceInfoUtil { .append(SimSignalUtil.hasSimCard(runtime.getContextProxy().context)?" SIM ":" NoSIM ") .append(sim.getNetworkType()==SimSignalUtil.IS_2G?"2G":(sim.getNetworkType()==SimSignalUtil.IS_3G)?"3G":(sim.getNetworkType()==SimSignalUtil.IS_4G?"4G":"unknown")) .append(" [").append(runtime.getSignalStrength()).append(",Mini:").append(SimSignalUtil.getMinSignalStrength(sim.getNetworkType())).append("]") - .append("\n KeepAlive ").append(KeepAlive.isConnected).append(" , HBcycle ").append(runtime.getHeartBeatCycle()) + .append("\n SocketConnection ").append(KeepAlive.isConnected).append(" , HBcycle ").append(runtime.getHeartBeatCycle()) .append("\n ServerConnected is ").append(runtime.isServerProtocolConnected()) .append(" \n Bat ").append(runtime.getBattery()).append(",").append(runtime.getBatteryVotage()) .append(" StepCount ").append(runtime.getTotalStepCount()) diff --git a/app/version_code.properties b/app/version_code.properties index e96a4120..d458487d 100644 --- a/app/version_code.properties +++ b/app/version_code.properties @@ -1,2 +1,2 @@ -#Mon Mar 02 23:37:05 CST 2020 -VERSION_CODE=367 +#Thu Mar 05 13:22:46 CST 2020 +VERSION_CODE=369