Browse Source

#CHANGE
- 1.修改tcp断网重连问题
- 2.修改webrtc断网重连出现anr问题
- 3.优化界面显示

weizhengliang 3 years ago
parent
commit
d471edc98d

+ 3 - 3
WebRTC/src/main/java/com/wdkl/core/socket/MyWebSocket.java

@@ -54,13 +54,13 @@ public class MyWebSocket extends WebSocketClient {
     public void onError(Exception ex) {
         Log.e("dds_error", "onError:" + ex.toString());
         this.iEvent.logout("onError");
-//        connectFlag = false;
-        try {
+        connectFlag = false;
+        /*try {
             Thread.sleep(3000);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
-        this.iEvent.reConnect();
+        this.iEvent.reConnect();*/
     }
 
     @Override

+ 7 - 0
WebRTC/src/main/java/com/wdkl/core/socket/SocketManager.java

@@ -373,6 +373,13 @@ public class SocketManager implements IEvent {
         });
     }
 
+    public boolean socketOpen() {
+        if (webSocket != null) {
+            return webSocket.isOpen();
+        }
+        return false;
+    }
+
     @Override
     public void reConnect() {
         handler.post(() -> {

+ 1 - 0
WebRTC/src/main/java/com/wdkl/core/voip/AsyncPlayer.java

@@ -77,6 +77,7 @@ public class AsyncPlayer {
                     case STOP:
                         if (mPlayer != null) {
                             mPlayer.stop();
+                            mPlayer.reset();
                             mPlayer.release();
                             mPlayer = null;
                         } else {

+ 51 - 8
home/src/main/code/com/wdkl/ncs/android/component/home/activity/HomeActivity.kt

@@ -1,10 +1,13 @@
 package com.wdkl.ncs.android.component.home.activity
 
 import android.Manifest
+import android.content.BroadcastReceiver
 import android.content.Context
 import android.content.Intent
+import android.content.IntentFilter
 import android.content.pm.PackageManager
 import android.graphics.Color
+import android.net.ConnectivityManager
 import android.os.Bundle
 import android.provider.Settings
 import android.support.v4.app.ActivityCompat
@@ -51,6 +54,7 @@ import com.wdkl.ncs.android.middleware.model.vo.DeviceVO
 import com.wdkl.ncs.android.middleware.model.vo.DeviceWatchInfoVO
 import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
 import com.wdkl.ncs.android.middleware.tcp.TcpClient
+import com.wdkl.ncs.android.middleware.tcp.TcpClientHandler
 import com.wdkl.ncs.android.middleware.tcp.channel.DeviceChannel
 import com.wdkl.ncs.android.middleware.tcp.channel.VideoUtil
 import com.wdkl.ncs.android.middleware.tcp.channel.VoiceUtil
@@ -82,6 +86,12 @@ class HomeActivity : BaseActivity<HomeActivityPresenter, ActivityHomeBinding>(),
 
     var currentFragment: Fragment? = null
 
+    var clickTime: Long = 0
+
+    var netAvailable: Boolean = false
+
+    private lateinit var receiver: TimeReceiver
+
     override fun getLayId(): Int {
         return R.layout.activity_home
     }
@@ -174,9 +184,14 @@ class HomeActivity : BaseActivity<HomeActivityPresenter, ActivityHomeBinding>(),
     }
 
     private fun regReceiver() {
+        receiver = TimeReceiver()
+        var intentFilter = IntentFilter()
+        intentFilter.addAction(Intent.ACTION_TIME_TICK)
+        registerReceiver(receiver, intentFilter)
     }
 
     private fun releaseReceiver(){
+        unregisterReceiver(receiver)
     }
 
     /**
@@ -266,10 +281,16 @@ class HomeActivity : BaseActivity<HomeActivityPresenter, ActivityHomeBinding>(),
 
         //问询事件
         btn_callout.setOnClickListener {
-            //loadingDialog.show()
-            //val tcpModel = VideoUtil.videoOutCall(Constants.deviceId)
-            //TcpClient.getInstance().sendMsg(tcpModel.toJson())
-            VideoUtil.startVideoOutCall(Constants.deviceId)
+            if (System.currentTimeMillis() - clickTime > 3000) {
+                if (TcpClientHandler.getConnected() && SocketManager.getInstance().socketOpen() && netAvailable) {
+                    VideoUtil.startVideoOutCall(Constants.deviceId)
+                } else {
+                    showMessage("通话服务或网络未连接,请检查网络稍后再试")
+                }
+            } else {
+                showMessage("点击太频繁")
+            }
+            clickTime = System.currentTimeMillis()
         }
     }
 
@@ -281,6 +302,7 @@ class HomeActivity : BaseActivity<HomeActivityPresenter, ActivityHomeBinding>(),
 
     override fun userLogin() {
         Log.i(TAG, "wdkl rtc 登录成功")
+        netAvailable = true
         runOnUiThread(Runnable {
             tv_rtc_status.setBackgroundColor(Color.GREEN)
         })
@@ -288,12 +310,13 @@ class HomeActivity : BaseActivity<HomeActivityPresenter, ActivityHomeBinding>(),
 
     override fun userLogout() {
         Log.w(TAG, "wdkl rtc 用户登出")
+        netAvailable = false
         runOnUiThread(Runnable {
             tv_rtc_status.setBackgroundColor(Color.RED)
         })
-        if (!SocketManager.getInstance().connectFlag) {
+        /*if (!SocketManager.getInstance().connectFlag) {
             reConnectRTC()
-        }
+        }*/
     }
 
     fun reConnectRTC(){
@@ -327,14 +350,14 @@ class HomeActivity : BaseActivity<HomeActivityPresenter, ActivityHomeBinding>(),
         releaseReceiver()
     }
 
-    /*override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
+    override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
         Log.i(TAG, "keyup keyCode " + keyCode)
         return if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {
             //不执行父类点击事件
             true
         } else super.onKeyUp(keyCode, event)
         //继续执行父类其他点击事件
-    }*/
+    }
 
     override fun bindEvent() {
     }
@@ -464,6 +487,26 @@ class HomeActivity : BaseActivity<HomeActivityPresenter, ActivityHomeBinding>(),
                 .add(R.id.frame_visit, currentFragment)
                 .commit()
             watch_activity_home_linyout.visibility = View.GONE
+        } else if (messageEvent.tag == Constants.EVENT_TCP_BREAK) {
+            if (TcpClientHandler.getConnected()) {
+                netAvailable = true
+            } else {
+                netAvailable = false
+                tv_rtc_status.setBackgroundColor(Color.RED)
+            }
+        }
+    }
+
+
+    inner class TimeReceiver: BroadcastReceiver() {
+        override fun onReceive(context: Context, intent: Intent) {
+            if (intent.action == Intent.ACTION_TIME_TICK) {
+                if (SocketManager.getInstance().socketOpen() && SocketManager.getInstance().userState == 1 && TcpClientHandler.getConnected()) {
+                    tv_rtc_status.setBackgroundColor(Color.GREEN)
+                } else {
+                    SocketManager.getInstance().connect(Urls.WS, Constants.sipId, 0)
+                }
+            }
         }
     }
 }

+ 2 - 7
home/src/main/code/com/wdkl/ncs/android/component/home/service/TcpHandleService.kt

@@ -7,14 +7,9 @@ import android.os.IBinder
 import android.util.Log
 import com.google.gson.Gson
 import com.wdkl.ncs.android.component.home.activity.*
-import com.wdkl.ncs.android.component.home.util.AppUtils
-import com.wdkl.ncs.android.component.home.util.SpeechUtil
 import com.wdkl.ncs.android.component.home.util.Util
 import com.wdkl.ncs.android.component.nursehome.common.Constants
-import com.wdkl.ncs.android.lib.utils.AppTool
 import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
-import com.wdkl.ncs.android.middleware.tcp.TcpClient
-import com.wdkl.ncs.android.middleware.tcp.TcpClientHandler
 import com.wdkl.ncs.android.middleware.tcp.channel.DeviceChannel
 import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel
 import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction
@@ -121,14 +116,14 @@ class TcpHandleService : Service(){
                 }
             }
             //网络断开,1000ms重连
-            Constants.EVENT_TCP_BREAK->{
+            /*Constants.EVENT_TCP_BREAK->{
                 var wakeLock = Util.wakeUpAndUnlock(this)
                 Thread(Runnable {
                     Thread.sleep(1000)
                     wakeLock?.release()
                 }).start()
                 Log.w(TAG, "EVENT TCP BREAK")
-            }
+            }*/
         }
     }
 }

+ 2 - 1
home/src/main/res/layout/activity_home.xml

@@ -8,7 +8,8 @@
         <FrameLayout
             android:id="@+id/frame_visit"
             android:layout_width="match_parent"
-            android:layout_height="match_parent"/>
+            android:layout_height="match_parent"
+            android:layout_marginTop="20dp"/>
 
        <include
           android:id="@+id/activity_register_layout"

+ 3 - 3
home/src/main/res/layout/call_dialog_lay.xml

@@ -21,10 +21,10 @@
 
         <ImageView
             android:id="@+id/iv_hangup_call"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+            android:layout_width="40dp"
+            android:layout_height="40dp"
             android:layout_marginTop="20dp"
-            android:src="@drawable/yu_yin_gua_duan" />
+            android:src="@drawable/av_hangup_selector" />
     </LinearLayout>
 
 

+ 2 - 2
home/src/main/res/layout/fragment_visit.xml

@@ -14,8 +14,8 @@
 
     <FrameLayout
         android:id="@+id/visit_pip_video_view"
-        android:layout_width="80dp"
-        android:layout_height="120dp"
+        android:layout_width="70dp"
+        android:layout_height="100dp"
         android:layout_gravity="top|end"
         android:layout_marginHorizontal="10dp"
         android:layout_marginTop="10dp" />

+ 2 - 2
home/src/main/res/layout/video_connected_action.xml

@@ -22,8 +22,8 @@
 
         <ImageView
             android:id="@+id/hangup_aciton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+            android:layout_width="40dp"
+            android:layout_height="40dp"
             android:src="@drawable/av_hangup_selector" />
 
         <TextView

+ 36 - 17
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/TcpClient.java

@@ -23,7 +23,7 @@ import io.netty.util.CharsetUtil;
 public class TcpClient {
     private String TAG = TcpClient.class.getSimpleName();
 
-    private NioEventLoopGroup workGroup = new NioEventLoopGroup(2);
+    private NioEventLoopGroup workGroup;
     public Channel channel;
     private Bootstrap bootstrap;
 
@@ -50,7 +50,9 @@ public class TcpClient {
 
     //初始化Netty Tcp Client 并连接
     public void init(String serverIP, Integer serverPort, Integer heartBeatSeconds) {
+
         final Integer hbSeconds = heartBeatSeconds;
+        workGroup = new NioEventLoopGroup(2);
         bootstrap = new Bootstrap();
         bootstrap.group(workGroup)
                 .channel(NioSocketChannel.class)
@@ -65,7 +67,8 @@ public class TcpClient {
                         // LengthFieldPrepender是一个编码器,主要是在响应字节数据前面添加字节长度字段
                         socketChannel.pipeline().addLast(new LengthFieldPrepender(2));
                         //心跳包应当小于服务器间隔
-                        socketChannel.pipeline().addLast(new IdleStateHandler(0, 0, hbSeconds, TimeUnit.SECONDS));
+//                        socketChannel.pipeline().addLast(new IdleStateHandler(0, hbSeconds, 0, TimeUnit.SECONDS));
+                        socketChannel.pipeline().addLast(new IdleStateHandler(hbSeconds*2, hbSeconds, 0, TimeUnit.SECONDS));
                         socketChannel.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8));
                         socketChannel.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
                         socketChannel.pipeline().addLast(tcpClientHandler);
@@ -91,31 +94,42 @@ public class TcpClient {
         System.out.println("TcpClient connect start");
         ChannelFuture future = bootstrap.connect().addListener(new ChannelFutureListener() {
             @Override
-            public void operationComplete(ChannelFuture channelFuture) throws Exception {
-                if (channelFuture.isSuccess()) {
-                    channel = channelFuture.channel();
+            public void operationComplete(final ChannelFuture channelFuture) throws Exception {
+                if (channelFuture.isSuccess()){
                     isRunning = true;
-                    retryTimes = 0;
-                    System.out.println("TcpClient connect success");
+                    channel = channelFuture.channel();
+                    retryTimes = 1;
+                    System.out.println("connect success");
                 } else {
                     //连接失败时的处理
                     isRunning = false;
-                    System.out.println("TcpClient connect retry : " + retryTimes);
+                    System.out.println("connect retry : " + retryTimes);
+                    //EventBus.getDefault().post(new MessageEvent(0, Constant.EVENT_TCP_STATE));
                     channelFuture.channel().eventLoop().schedule(new Runnable() {
                         @Override
                         public void run() {
                             retryTimes++;
-                            if (retryTimes > 30) {
-                                System.out.println("TcpClient 重试" + (retryTimes - 1) + "次,结束");
-                                workGroup.shutdownGracefully();
-                                inited = false;
-                                //从API获取新的serverIP和serverPort,全新连接
-                                TcpClient.getInstance().init(Constants.Companion.getTcpServer(), Constants.Companion.getTcpPort(), Constants.Companion.getHeartBeat());
-                                return;
+                            if (retryTimes > 20) { //重试30次还没连成功,等10分钟后再试
+//                                System.out.println("TcpClient 重试" + (retryTimes - 1) + "次,结束");
+//                                channel.close();
+//                                workGroup.shutdownGracefully();
+//                                //todo: 从API获取新的serverIP和serverPort,全新连接
+//                                TcpClient.getInstance().init(Constant.TCP_SERVER_URL, Constant.TCP_PORT, Constant.TCP_HEART_BEAT);
+                                retryTimes=1;
+                                channelFuture.channel().eventLoop().schedule(new Runnable() {
+                                    @Override
+                                    public void run() {
+                                        System.out.println("TcpClientHandler 重新连接,第" + retryTimes + "次");
+                                        doConnect();
+                                    }
+                                }, 60*10, TimeUnit.SECONDS);
+
+                            }else{
+                                doConnect();
                             }
-                            doConnect();
+
                         }
-                    }, retrySeconds * retryTimes, TimeUnit.SECONDS);
+                    }, 5, TimeUnit.SECONDS);
                 }
             }
         });
@@ -142,6 +156,11 @@ public class TcpClient {
         }
     }
 
+
+    public Channel getChannel() {
+        return channel;
+    }
+
     //测试
     public static void main(String[] args) {
 

+ 32 - 27
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/TcpClientHandler.java

@@ -50,6 +50,7 @@ public class TcpClientHandler extends SimpleChannelInboundHandler<String> {
         retryTimes = 0;
         retrySendMsg = 0;
 
+        EventBus.getDefault().post(new MessageEvent("net on",Constants.EVENT_TCP_BREAK));
         TcpModel tcpModel = DeviceUtil.deviceConnect(Constants.Companion.getImei());
         TcpClient.getInstance().sendMsg(tcpModel.toJson());
     }
@@ -61,6 +62,7 @@ public class TcpClientHandler extends SimpleChannelInboundHandler<String> {
         connected = false;
         this.ctx = null;
         Log.i(TAG, "TcpClientHandler 失去连接");
+        EventBus.getDefault().post(new MessageEvent("net off",Constants.EVENT_TCP_BREAK));
 
         TcpClient.getInstance().doConnect();
         //reConnect(ctx);
@@ -77,7 +79,7 @@ public class TcpClientHandler extends SimpleChannelInboundHandler<String> {
 
             TcpModel responseTcpModel = DeviceChannel.handleTcpReceived(tcpModel);
             if (responseTcpModel!=null){
-                TcpClient.getInstance().sendMsg(responseTcpModel.toJson());
+                ctx.writeAndFlush(responseTcpModel.toJson());
             } else {
                 ReferenceCountUtil.release(source);
             }
@@ -87,18 +89,15 @@ public class TcpClientHandler extends SimpleChannelInboundHandler<String> {
     //写心跳包。没有消息发送时,每间隔一定时间会由此方法向服务端发送心跳
     @Override
     public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
-        if (evt instanceof IdleStateEvent){
-            IdleStateEvent event = (IdleStateEvent)evt;
-            if (event.state()== IdleState.WRITER_IDLE){
-                //读心跳包超时执行
-                Log.i(TAG,"TcpClientHandler ===> WRITER_IDLE");
-            } else if (event.state() == IdleState.READER_IDLE){
-                //写心跳包超时
-                Log.i(TAG,"TcpClientHandler ===> READER_IDLE");
-            } else if (event.state() == IdleState.ALL_IDLE){
-                //写心跳包超时
-                Log.i(TAG,"TcpClientHandler ===> ALL_IDLE");
-                ctx.writeAndFlush("0");
+        if (evt instanceof IdleStateEvent) {
+            IdleStateEvent event = (IdleStateEvent) evt;
+            if (event.state() == IdleState.WRITER_IDLE) { //超时未执行写操作,在指定的超时时间内未有写操作,要发送心跳包,告诉服务器连接还存活。服务器收到心跳立马回应,正常客户端收到后执行读操作,
+                ctx.writeAndFlush("0");                //这种情况下不会引发READER_IDLE事件。如果服务器因为网络或其他原因导致回应的心跳,客户端没有收到,在超过写超时时间2个周期后依然没有收到,
+            } else if (event.state() == IdleState.READER_IDLE) { //认为服务不可用,主动断开连接
+                Log.i(TAG, "TcpClientHandler ===> READER_IDLE");
+                ctx.close();
+            } else if (event.state() == IdleState.ALL_IDLE) {
+                Log.i(TAG, "TcpClientHandler ===> ALL_IDLE");
             }
         }
     }
@@ -145,21 +144,27 @@ public class TcpClientHandler extends SimpleChannelInboundHandler<String> {
         totalRetryTimes++;
         Log.i(TAG,"TcpClientHandler 总计连接次数:"+totalRetryTimes);
         retryTimes++;
-        if (retryTimes>30){
-            //超时3次,其它处理
-            Log.i(TAG,"TcpClientHandler 重新连接"+(retryTimes-1)+"次,结束");
+        if (retryTimes > 30) { //超时30次,10分钟后再试
             retryTimes = 0;
-            //todo: 从API获取新的serverIP和serverPort,全新连接
-            //TcpClient.getInstance().init();
-            return;
-        }
+            ctx.channel().eventLoop().schedule(new Runnable() {
+                @Override
+                public void run() {
+                    System.out.println("TcpClientHandler 重新连接,第" + retryTimes + "次");
+                    TcpClient.getInstance().doConnect();
+                    reConnect(ctx);
+                }
+            }, 10*60, TimeUnit.SECONDS);
 
-        ctx.channel().eventLoop().schedule(new Runnable() {
-            @Override
-            public void run() {
-                System.out.println("TcpClientHandler 重新连接,第"+retryTimes+"次");
-                TcpClient.getInstance().doConnect();
-            }
-        },retrySeconds*retryTimes, TimeUnit.SECONDS);
+
+        }else {
+            ctx.channel().eventLoop().schedule(new Runnable() {
+                @Override
+                public void run() {
+                    System.out.println("TcpClientHandler 重新连接,第" + retryTimes + "次");
+                    TcpClient.getInstance().doConnect();
+                    reConnect(ctx);
+                }
+            }, retrySeconds * retryTimes, TimeUnit.SECONDS);
+        }
     }
 }