[Fix]解决乘客屏断线重连的Bug

原因:以前Client断线重连机制是基于Server不变的情况下,直接取内存中缓存的之前连接成功的Server端ip,
而实际上司机屏断线重连后ip改变了
This commit is contained in:
chenfufeng
2022-08-29 15:57:33 +08:00
parent 02fc359dbb
commit db14b0483d
5 changed files with 99 additions and 28 deletions

View File

@@ -1,7 +1,10 @@
package com.mogo.telematic;
import static com.mogo.telematic.client.status.ConnectState.STATUS_CONNECT_CLOSED;
import android.content.Context;
import android.net.nsd.NsdServiceInfo;
import android.os.CountDownTimer;
import com.elegant.log.simplelog.Logger;
import com.mogo.telematic.client.NettyTcpClient;
@@ -27,6 +30,9 @@ public class NSDNettyManager {
private static final String TAG = "NSDNettyManager";
private static final long COUNTDOWN_TIME = 70 * 1000;
private static final long INTERVAL_TIME = 30 * 1000;
private volatile static NSDNettyManager sInstance;
// client端用来过滤的
public static final String SERVER_NAME = "NSD_SERVER";
@@ -45,6 +51,10 @@ public class NSDNettyManager {
private String currentIp8 = "192.168.8.0";
private String currentIp = currentIp1;
// 重新扫描时使用
private String mUuid;
private boolean mIsTaxi;
private NettyClientListener mClientListener;
private NSDNettyManager() {
}
@@ -208,6 +218,11 @@ public class NSDNettyManager {
* @param context
*/
public void searchAndConnectServer(Context context, String uuid, boolean isTaxi, NettyClientListener listener) {
// 保存变量,给后续重新扫描使用
mContext = context;
mUuid = uuid;
mIsTaxi = isTaxi;
mClientListener = listener;
if (isTaxi) {
// 这里暂时关闭原因是因为BUS上无法透穿虚拟机的网络限制
if (mNsdClient == null) {
@@ -218,11 +233,14 @@ public class NSDNettyManager {
String hostAddress = info.getHost().getHostAddress();
Logger.d(TAG, "NSD查询到指定服务器信息ip为" + hostAddress + ",port为" + port);
//获取到指定的地址进行Netty的连接
connectNettyServer(hostAddress, port, uuid, listener);
connectNettyServer(hostAddress, port, uuid);
if (info.getServiceName().startsWith(SERVER_NAME)) {
//扫描到以后停止
mNsdClient.stopServiceDiscovery();
if (mNsdClient != null) {
mNsdClient.stopServiceDiscovery();
mNsdClient = null;
}
}
}
}
@@ -246,6 +264,7 @@ public class NSDNettyManager {
// 启动发现司机屏幕任务
mDiscoveryTask = new DiscoveryDriverTask();
network_ip = NetInfo.getUnsignedLongFromIp(currentIp);
mClientListener = listener;
int cidr = 24;
// Detected IP
@@ -273,7 +292,7 @@ public class NSDNettyManager {
hostAddress = hostBean.ipAddress;
Logger.d(TAG, "NSD查询到指定服务器信息ip为" + hostAddress + ",port为" + 1088);
//获取到指定的地址进行Netty的连接
connectNettyServer(hostAddress, 1088, uuid, listener);
connectNettyServer(hostAddress, 1088, uuid);
}
} else {
Logger.d(TAG, "扫描完成,未找到可连接司机屏幕服务");
@@ -295,7 +314,7 @@ public class NSDNettyManager {
mDiscoveryTask.execute();
}
private void connectNettyServer(String serverAddress, int port, String sign, NettyClientListener listener) {
private void connectNettyServer(String serverAddress, int port, String sign) {
Logger.d(TAG, "connectNettyServer");
if (serverAddress == null || serverAddress.length() == 0) {
Logger.e(TAG, "Netty Server的ip不能为空");
@@ -312,8 +331,28 @@ public class NSDNettyManager {
.setHeartBeatData(new MogoProtocolMsg(MogoProtocolMsg.HEART_DATA, 2, new byte[]{0x00, 0x00})) //设置心跳数据可以是String类型也可以是byte[],以后设置的为准
.setSign(sign) //设置客户端标识.(因为可能存在多个tcp连接)
.build();
if (listener != null) {
mNettyTcpClient.setListener(listener); //设置TCP监听
// TODO:("断开连接时关闭原有EventGroup并重新扫描ip")
mNettyTcpClient.setListener(new NettyClientListener() {
@Override
public void onMessageResponseClient(Object msg, String sign, Channel channel) {
if (mClientListener != null) {
mClientListener.onMessageResponseClient(msg, sign, channel);
}
}
@Override
public void onClientStatusConnectChanged(int statusCode, String content, Channel channel) {
if (mClientListener != null) {
mClientListener.onClientStatusConnectChanged(statusCode, content, channel);
}
if (statusCode == STATUS_CONNECT_CLOSED) {
// 开启重连倒计时(70s)
new CustomTimer(COUNTDOWN_TIME, INTERVAL_TIME).start();
}
}
});
if (mClientListener != null) {
mNettyTcpClient.setListener(mClientListener); //设置TCP监听
}
}
@@ -361,6 +400,7 @@ public class NSDNettyManager {
* @param ip
*/
public void connectSpecifiedServer(String ip, int port, String uuid, NettyClientListener listener) {
mClientListener = listener;
if (mNsdClient != null) {
// 停止局域网内扫描
mNsdClient.stopServiceDiscovery();
@@ -370,7 +410,7 @@ public class NSDNettyManager {
mNettyTcpClient.disconnect();
mNettyTcpClient = null;
}
connectNettyServer(ip, port, uuid, listener);
connectNettyServer(ip, port, uuid);
}
public static String bytesToHexFun(byte[] bytes, int length) {
@@ -389,4 +429,24 @@ public class NSDNettyManager {
mNettyTcpClient.disconnect();
}
}
public class CustomTimer extends CountDownTimer {
public CustomTimer(long total, long interval) {
super(total, interval);
}
@Override
public void onTick(long millisUntilFinished) {
}
@Override
public void onFinish() {
// 倒计时结束关闭客户端EventGroup重新扫描ip
cancel();
disconnect();
searchAndConnectServer(mContext, mUuid, mIsTaxi, mClientListener);
}
}
}

View File

@@ -169,7 +169,9 @@ public class NettyTcpClient {
synchronized (NettyTcpClient.this) {
if (!isConnected) {
isConnecting = true;
group = new NioEventLoopGroup();
if (group == null || group.isShutdown()) {
group = new NioEventLoopGroup();
}
initBootstrap();
doConnect();
} else {
@@ -272,6 +274,8 @@ public class NettyTcpClient {
Log.e(TAG, "disconnect");
isNeedReconnect = false;
group.shutdownGracefully();
group = null;
bootstrap = null;
}
public boolean sendMsgToServer(MogoProtocolMsg protocolMsg, final MessageStateListener listener) {

View File

@@ -16,6 +16,7 @@ class ReconnectHandler(
) : ChannelInboundHandlerAdapter() {
private val maxRetries = Int.MAX_VALUE
@Volatile
private var retries = 0
private val baseSleepTimeMs = 3000
private val maxSleepMs = 10 * 1000
@@ -45,14 +46,16 @@ class ReconnectHandler(
@Throws(Exception::class)
override fun channelInactive(ctx: ChannelHandlerContext) {
Logger.d(TAG, "ReconnectHandler channelInactive ...")
synchronized(NettyTcpClient::class.java) {
NettyTcpClient.sSERVER_SN = ""
if (retries == 0) {
synchronized(NettyTcpClient::class.java) {
NettyTcpClient.sSERVER_SN = ""
}
listener.onClientStatusConnectChanged(
STATUS_CONNECT_CLOSED,
"channelInactive",
ctx.channel()
)
}
listener.onClientStatusConnectChanged(
STATUS_CONNECT_CLOSED,
"channelInactive",
ctx.channel()
)
var allowRetry = false
if (retries < maxRetries) {
allowRetry = true