From 95f1e1c0fb9f8501630c349de61859826963ca90 Mon Sep 17 00:00:00 2001
From: lizhanwei <Dana_Lee1016@126.com>
Date: 星期六, 22 二月 2020 14:46:32 +0800
Subject: [PATCH] 设定IdleStateHandler心跳检测每四秒进行一次写检测,如果四秒内write()方法未被调用则触发一次userEventTrigger()方法,实现客户端每四秒向服务端发送一次心跳消息

---
 app/src/main/java/safeluck/drive/evaluation/MainActivity.java          |    1 
 app/src/main/java/safeluck/drive/evaluation/im/IMSEventListener.java   |   12 +++
 app/src/main/java/safeluck/drive/evaluation/im/IMessageProcessor.java  |    2 
 im_lib/src/main/java/com/anyun/im_lib/IMSConfig.java                   |    2 
 im_lib/src/main/java/com/anyun/im_lib/netty/NettyTcpClient.java        |   60 ++++++++++++++++++++
 im_lib/src/main/java/com/safeluck/aykj/message/BinMessageBase.java     |    5 -
 im_lib/src/main/java/com/anyun/im_lib/listener/OnEventListener.java    |    2 
 im_lib/src/main/java/com/anyun/im_lib/HeartbeatHandler.java            |   53 +++++++++++++++++
 app/src/main/java/safeluck/drive/evaluation/fragment/TcpFragment.java  |    2 
 app/src/main/java/safeluck/drive/evaluation/im/IMSClientBootstrap.java |    6 ++
 im_lib/src/main/java/com/anyun/im_lib/interf/IMSClientInteface.java    |    4 +
 app/src/main/java/safeluck/drive/evaluation/im/MessageProcessor.java   |    8 ++
 12 files changed, 151 insertions(+), 6 deletions(-)

diff --git a/app/src/main/java/safeluck/drive/evaluation/MainActivity.java b/app/src/main/java/safeluck/drive/evaluation/MainActivity.java
index 9660920..4f9650c 100644
--- a/app/src/main/java/safeluck/drive/evaluation/MainActivity.java
+++ b/app/src/main/java/safeluck/drive/evaluation/MainActivity.java
@@ -321,6 +321,7 @@
         MyLog.i(TAG,"TCP杩炴帴鎴愬姛");
         //TODO 鍒ゆ柇SPUtils 鏄惁淇濆瓨鏈塪es瀵嗙爜锛涘鏋滄病鏈夊垯杩涜娉ㄥ唽JKMessage0100锛屽鏋滄湁瀵嗙爜鍒欒繘琛岄壌鏉僇KMessage0101
         String hexPwd = (String) SPUtils.get(this,SPUtils.DES_HEX_PWD,"");
+        MessageProcessor.getInstance().addBeatHeart(10);
         if (TextUtils.isEmpty(hexPwd)){
 
             JKMessage0100 jkRegisterMessage = new JKMessage0100();
diff --git a/app/src/main/java/safeluck/drive/evaluation/fragment/TcpFragment.java b/app/src/main/java/safeluck/drive/evaluation/fragment/TcpFragment.java
index 4ebbd28..b636ff8 100644
--- a/app/src/main/java/safeluck/drive/evaluation/fragment/TcpFragment.java
+++ b/app/src/main/java/safeluck/drive/evaluation/fragment/TcpFragment.java
@@ -291,7 +291,7 @@
                     @Override
                     public void run() {
                         JKMessage0002 jkMessage0002 = new JKMessage0002();
-                        jkMessage0002.checksum = 0x7e;
+//                        jkMessage0002.checksum = 0x7e;
                         MessageProcessor.getInstance().sendMessage(jkMessage0002);
                         Log.i(TAG, "run: 5s涓�娆�");
                     }
diff --git a/app/src/main/java/safeluck/drive/evaluation/im/IMSClientBootstrap.java b/app/src/main/java/safeluck/drive/evaluation/im/IMSClientBootstrap.java
index a09fd98..fa0becf 100644
--- a/app/src/main/java/safeluck/drive/evaluation/im/IMSClientBootstrap.java
+++ b/app/src/main/java/safeluck/drive/evaluation/im/IMSClientBootstrap.java
@@ -107,4 +107,10 @@
             imsClient.sendMsg(message);
         }
     }
+
+    public void addHeartbeat(int seconds){
+        if (isActive){
+            imsClient.addHeartbeatHandler(seconds);
+        }
+    }
 }
diff --git a/app/src/main/java/safeluck/drive/evaluation/im/IMSEventListener.java b/app/src/main/java/safeluck/drive/evaluation/im/IMSEventListener.java
index 59bb12b..2874640 100644
--- a/app/src/main/java/safeluck/drive/evaluation/im/IMSEventListener.java
+++ b/app/src/main/java/safeluck/drive/evaluation/im/IMSEventListener.java
@@ -2,6 +2,9 @@
 
 import com.anyun.im_lib.listener.OnEventListener;
 
+import safeluck.drive.evaluation.platformMessage.JKMessage0002;
+import safeluck.drive.evaluation.platformMessage.utils.MessageEscaper;
+
 /**
  * MyApplication2
  * Created by lzw on 2019/12/12. 16:12:40
@@ -12,10 +15,11 @@
 
     private String userId;
     private String token;
-
+    private MessageEscaper messageEscaper;
     public IMSEventListener(String userId, String token) {
         this.userId = userId;
         this.token = token;
+        messageEscaper = new MessageEscaper();
     }
 
     @Override
@@ -71,4 +75,10 @@
     public byte[] getRegisterMessage() {
         return null;
     }
+
+    @Override
+    public byte[] getHearbeatMsg() {
+        JKMessage0002 jkMessage0002 = new JKMessage0002();
+        return messageEscaper.escape(jkMessage0002.toBytes());
+    }
 }
diff --git a/app/src/main/java/safeluck/drive/evaluation/im/IMessageProcessor.java b/app/src/main/java/safeluck/drive/evaluation/im/IMessageProcessor.java
index 7121a36..c685223 100644
--- a/app/src/main/java/safeluck/drive/evaluation/im/IMessageProcessor.java
+++ b/app/src/main/java/safeluck/drive/evaluation/im/IMessageProcessor.java
@@ -11,4 +11,6 @@
 public interface IMessageProcessor {
     void receiveMsg(byte[] message);
     void sendMessage(JK2019MessageBase msg);
+
+    void addBeatHeart(int seconds);
 }
diff --git a/app/src/main/java/safeluck/drive/evaluation/im/MessageProcessor.java b/app/src/main/java/safeluck/drive/evaluation/im/MessageProcessor.java
index 8c4ca12..3cf3798 100644
--- a/app/src/main/java/safeluck/drive/evaluation/im/MessageProcessor.java
+++ b/app/src/main/java/safeluck/drive/evaluation/im/MessageProcessor.java
@@ -8,6 +8,7 @@
 import androidx.work.WorkManager;
 
 import com.anyun.exam.lib.MyLog;
+import com.anyun.im_lib.interf.IMSClientInteface;
 import com.anyun.im_lib.util.ByteUtil;
 import com.google.gson.Gson;
 import com.safeluck.aykj.utils.BytesUtils;
@@ -105,4 +106,11 @@
             }
         });
     }
+
+    @Override
+    public void addBeatHeart(int seconds) {
+        if (IMSClientBootstrap.getInstance().isActive()){
+            IMSClientBootstrap.getInstance().addHeartbeat(seconds);
+        }
+    }
 }
diff --git a/im_lib/src/main/java/com/anyun/im_lib/HeartbeatHandler.java b/im_lib/src/main/java/com/anyun/im_lib/HeartbeatHandler.java
index a0e4314..f85db3a 100644
--- a/im_lib/src/main/java/com/anyun/im_lib/HeartbeatHandler.java
+++ b/im_lib/src/main/java/com/anyun/im_lib/HeartbeatHandler.java
@@ -1,6 +1,13 @@
 package com.anyun.im_lib;
 
+import com.anyun.im_lib.netty.NettyTcpClient;
+import com.anyun.im_lib.util.MyLog;
+import com.safeluck.aykj.utils.BytesUtils;
+
+import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.handler.timeout.IdleState;
+import io.netty.handler.timeout.IdleStateEvent;
 
 /**
  * MyApplication2
@@ -9,4 +16,50 @@
  * All Rights Saved! Chongqing AnYun Tech co. LTD
  */
 public class HeartbeatHandler extends ChannelInboundHandlerAdapter  {
+    private NettyTcpClient imsClient;
+    public HeartbeatHandler(NettyTcpClient imsClient) {
+        this.imsClient = imsClient;
+    }
+    private HeartbeatTask heartbeatTask;
+    private class HeartbeatTask implements Runnable {
+
+        private ChannelHandlerContext ctx;
+
+        public HeartbeatTask(ChannelHandlerContext ctx) {
+            this.ctx = ctx;
+        }
+
+        @Override
+        public void run() {
+            if (ctx.channel().isActive()) {
+                byte []heartbeatMsg = imsClient.getHeartbeatMsg();
+                if (heartbeatMsg == null) {
+                    return;
+                }
+                MyLog.i("鍙戦�佸績璺虫秷鎭紝message=" +  BytesUtils.bytesToHexString(heartbeatMsg) + "褰撳墠蹇冭烦闂撮殧涓猴細" +imsClient.getHeartbeatInterval() + "ms\n");
+                imsClient.sendMsg(heartbeatMsg, false);
+            }
+        }
+    }
+    @Override
+    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
+        super.userEventTriggered(ctx, evt);
+        if (evt instanceof IdleStateEvent){
+            IdleState state = ((IdleStateEvent)evt).state();
+            MyLog.i("Netty TCP Idlestate="+state.name());
+            switch (state){
+                case READER_IDLE:
+                    // 瑙勫畾鏃堕棿鍐呮病鏀跺埌鏈嶅姟绔績璺冲寘鍝嶅簲锛岃繘琛岄噸杩炴搷浣�
+                    break;
+                case WRITER_IDLE:
+                    // 瑙勫畾鏃堕棿鍐呮病鍚戞湇鍔$鍙戦�佸績璺冲寘锛屽嵆鍙戦�佷竴涓績璺冲寘
+                    if (heartbeatTask == null) {
+                        heartbeatTask = new HeartbeatTask(ctx);
+                    }
+                    imsClient.getLoopGroup().execWorkTask(heartbeatTask);
+                    break;
+
+            }
+        }
+    }
 }
diff --git a/im_lib/src/main/java/com/anyun/im_lib/IMSConfig.java b/im_lib/src/main/java/com/anyun/im_lib/IMSConfig.java
index 646ad15..4950e7a 100644
--- a/im_lib/src/main/java/com/anyun/im_lib/IMSConfig.java
+++ b/im_lib/src/main/java/com/anyun/im_lib/IMSConfig.java
@@ -10,7 +10,7 @@
     public static final int CONNECT_STATE_FAILURE = -1;
     public static final int DEFAULT_RECONNECT_BASE_DELAY_TIME = 3 * 1000;
     public static final int DEFAULT_CONNECT_TIMEOUT = 10 * 1000;
-    public static final int DEFAULT_HEARTBEAT_INTERVAL_FOREGROUND = 3 * 1000;
+    public static final int DEFAULT_HEARTBEAT_INTERVAL_FOREGROUND = 10 * 1000;
     public static final int DEFAULT_HEARTBEAT_INTERVAL_BACKGROUND = 30 * 1000;
 
     /*** 搴旂敤鍦ㄥ墠鍙版爣璇�***/
diff --git a/im_lib/src/main/java/com/anyun/im_lib/interf/IMSClientInteface.java b/im_lib/src/main/java/com/anyun/im_lib/interf/IMSClientInteface.java
index a50730d..2b55154 100644
--- a/im_lib/src/main/java/com/anyun/im_lib/interf/IMSClientInteface.java
+++ b/im_lib/src/main/java/com/anyun/im_lib/interf/IMSClientInteface.java
@@ -112,4 +112,8 @@
 
 //鑾峰彇娉ㄥ唽娑堟伅
     byte[] getRegisterMessage();
+
+    byte[] getHeartbeatMsg();
+
+    void addHeartbeatHandler(int seconds);
 }
diff --git a/im_lib/src/main/java/com/anyun/im_lib/listener/OnEventListener.java b/im_lib/src/main/java/com/anyun/im_lib/listener/OnEventListener.java
index ae61ce2..ccd7c2f 100644
--- a/im_lib/src/main/java/com/anyun/im_lib/listener/OnEventListener.java
+++ b/im_lib/src/main/java/com/anyun/im_lib/listener/OnEventListener.java
@@ -59,4 +59,6 @@
     int getReConnectInterval();
 //娉ㄥ唽娑堟伅
     byte[] getRegisterMessage();
+
+    byte[] getHearbeatMsg();
 }
diff --git a/im_lib/src/main/java/com/anyun/im_lib/netty/NettyTcpClient.java b/im_lib/src/main/java/com/anyun/im_lib/netty/NettyTcpClient.java
index aec3868..0c6112b 100644
--- a/im_lib/src/main/java/com/anyun/im_lib/netty/NettyTcpClient.java
+++ b/im_lib/src/main/java/com/anyun/im_lib/netty/NettyTcpClient.java
@@ -17,6 +17,7 @@
 
 import java.nio.ByteBuffer;
 import java.util.Vector;
+import java.util.concurrent.TimeUnit;
 import java.util.function.ToDoubleBiFunction;
 
 import io.netty.bootstrap.Bootstrap;
@@ -405,6 +406,34 @@
         return null;
     }
 
+    @Override
+    public byte[] getHeartbeatMsg() {
+        if (mOnEventListener != null){
+            return mOnEventListener.getHearbeatMsg();
+        }
+        return null;
+    }
+
+
+
+    /**
+     * 澧炲姞蹇冭烦锛�
+     * @param heartBeatInterval 绉�
+     */
+    @Override
+    public void addHeartbeatHandler(int heartBeatInterval){
+        this.heartBeatInterval = heartBeatInterval*1000;
+        _addHeartbeatHandler();
+    }
+
+    public int getHeartbeatInterval() {
+        return this.heartBeatInterval;
+    }
+
+    public ExecutorServiceFactory getLoopGroup() {
+        return loopGroup;
+    }
+
 
     /**
      * 閲嶈繛浠诲姟
@@ -522,6 +551,37 @@
     }
 
 
+    private void _addHeartbeatHandler(){
+        MyLog.i("add HeartbeatHandler");
+        if (channel == null || !channel.isActive() || channel.pipeline()==null){
+            MyLog.i("PlatformMessage","娣诲姞蹇冭烦handler澶辫触");
+            return;
+        }
+        try {
+            if(channel.pipeline().get(IdleStateHandler.class.getSimpleName()) != null){
+                MyLog.i("PlatformMessage","涔嬪墠瀛樺湪鐨勮鍐欒秴鏃秇andler锛屽厛绉婚櫎鎺夛紝鍐嶉噸鏂版坊鍔�");
+                channel.pipeline().remove(IdleStateHandler.class.getSimpleName());
+            }
+            // 3娆″績璺虫病鍝嶅簲锛屼唬琛ㄨ繛鎺ュ凡鏂紑
+            //璁惧畾IdleStateHandler蹇冭烦妫�娴嬫瘡鍥涚杩涜涓�娆″啓妫�娴嬶紝濡傛灉鍥涚鍐厀rite()鏂规硶鏈璋冪敤鍒欒Е鍙戜竴娆serEventTrigger()鏂规硶锛屽疄鐜板鎴风姣忓洓绉掑悜鏈嶅姟绔彂閫佷竴娆℃秷鎭紱
+            channel.pipeline().addFirst(IdleStateHandler.class.getSimpleName(), new IdleStateHandler(
+                    0, heartBeatInterval, 0, TimeUnit.MILLISECONDS));
+
+            // 閲嶆柊娣诲姞HeartbeatHandler
+            if (channel.pipeline().get(HeartbeatHandler.class.getSimpleName()) != null) {
+                channel.pipeline().remove(HeartbeatHandler.class.getSimpleName());
+            }
+            if (channel.pipeline().get(TCPReadHandler.class.getSimpleName()) != null) {
+                MyLog.i("涔嬪墠瀛樺湪鐨勫厛绉婚櫎鎺夛紝鍐嶉噸鏂版坊鍔燞eartbeatHandler");
+                channel.pipeline().addBefore(TCPReadHandler.class.getSimpleName(), HeartbeatHandler.class.getSimpleName(),
+                        new HeartbeatHandler(this));
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            MyLog.i("娣诲姞蹇冭烦娑堟伅绠$悊handler澶辫触锛宺eason锛�" + e.getMessage());
+        }
+    }
+
 
 
 }
diff --git a/im_lib/src/main/java/com/safeluck/aykj/message/BinMessageBase.java b/im_lib/src/main/java/com/safeluck/aykj/message/BinMessageBase.java
index c483dfa..a363991 100644
--- a/im_lib/src/main/java/com/safeluck/aykj/message/BinMessageBase.java
+++ b/im_lib/src/main/java/com/safeluck/aykj/message/BinMessageBase.java
@@ -168,7 +168,7 @@
             try {
                 Object value = fieldDefine.field.get(this);
                 String hex = fieldDefine.coder.encode(value);
-                Log.i("PlatformMessage", "FieldName: "+fieldDefine.field.getName()+" hex:"+hex);
+//                Log.i("PlatformMessage", "FieldName: "+fieldDefine.field.getName()+" hex:"+hex);
                 if (hex == null) {
                     fieldDefine.relativeLengthField.set(this, 0);
                 } else {
@@ -211,8 +211,7 @@
                         hex = this.getPaddingLeftString(hex,fieldDefine.getFieldLen()*2, BytesUtils.toHexString(fieldDefine.length.paddingByte()));
                     }
                 }
-//                System.out.println(hex);
-                Log.i("PlatformMessage value", "FieldName: "+fieldDefine.field.getName()+" hex:"+hex);
+//                Log.i("PlatformMessage value", "FieldName: "+fieldDefine.field.getName()+" hex:"+hex);
                 sb.append(hex);
             } catch (IllegalAccessException e) {
                 this.buildException(e.getMessage());

--
Gitblit v1.8.0