From 704a7434b0494e84a578d719daacb72f995b2ad2 Mon Sep 17 00:00:00 2001
From: yy1717 <fctom1215@outlook.com>
Date: 星期一, 30 十二月 2019 17:43:17 +0800
Subject: [PATCH] Merge branch 'master' of https://gitee.com/endian11/DriveJudge

---
 im_lib/src/main/java/com/anyun/im_lib/LoginAuthRespHandler.java               |   12 
 im_lib/src/main/java/com/anyun/im_lib/listener/IMSConnectStatusCallback.java  |    2 
 im_lib/src/main/java/com/anyun/im_lib/util/ByteUtil.java                      |  209 +++++++++++++++++++
 settings.gradle                                                               |    2 
 im_lib/src/main/java/com/anyun/im_lib/IMSConfig.java                          |    1 
 im_lib/src/main/java/com/anyun/im_lib/netty/TCPChannelInitializerHandler.java |   37 +++
 im_lib/src/main/java/com/anyun/im_lib/MsgDispatcher.java                      |   12 +
 im_lib/src/main/java/com/anyun/im_lib/netty/NettyTcpClient.java               |  296 ++++++++++++++++++++------
 im_lib/src/main/java/com/anyun/im_lib/ExecutorServiceFactory.java             |    5 
 im_lib/src/main/java/com/anyun/im_lib/listener/OnEventListener.java           |   11 +
 im_lib/src/main/java/com/anyun/im_lib/netty/TCPReadHandler.java               |   13 +
 im_lib/src/main/java/com/anyun/im_lib/interf/IMSClientInteface.java           |    3 
 12 files changed, 520 insertions(+), 83 deletions(-)

diff --git a/im_lib/src/main/java/com/anyun/im_lib/ExecutorServiceFactory.java b/im_lib/src/main/java/com/anyun/im_lib/ExecutorServiceFactory.java
index 410c052..37e9ede 100644
--- a/im_lib/src/main/java/com/anyun/im_lib/ExecutorServiceFactory.java
+++ b/im_lib/src/main/java/com/anyun/im_lib/ExecutorServiceFactory.java
@@ -1,5 +1,7 @@
 package com.anyun.im_lib;
 
+import android.util.Log;
+
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -10,6 +12,8 @@
  * All Rights Saved! Chongqing AnYun Tech co. LTD
  */
 public class ExecutorServiceFactory {
+
+    private static final String TAG = ExecutorServiceFactory.class.getSimpleName();
 
     /*** 绠$悊绾跨▼缁勶紝璐熻矗閲嶈繛***/
     private ExecutorService bossPool;
@@ -38,6 +42,7 @@
         if (bossPool == null){
             initBossLoopGroup();
         }
+        Log.i(TAG, "execBossTask");
         bossPool.execute(runnable);
     }
     /**
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 b091c5c..646ad15 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
@@ -25,4 +25,5 @@
     public static final int DEFAULT_RECONNECT_INTERVAL = 3 * 1000;
     public static final int CONNECT_STATE_CONNECTING = 0;
     public static final int CONNECT_STATE_SUCCESSFUL = 1;
+    public static final int DEFAULT_RECONNECT_COUNT = 3;
 }
diff --git a/im_lib/src/main/java/com/anyun/im_lib/LoginAuthRespHandler.java b/im_lib/src/main/java/com/anyun/im_lib/LoginAuthRespHandler.java
index a3c6191..a91f238 100644
--- a/im_lib/src/main/java/com/anyun/im_lib/LoginAuthRespHandler.java
+++ b/im_lib/src/main/java/com/anyun/im_lib/LoginAuthRespHandler.java
@@ -4,6 +4,7 @@
 
 import com.anyun.im_lib.interf.IMSClientInteface;
 
+import io.netty.buffer.ByteBuf;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 
@@ -14,10 +15,17 @@
  * 閭锛�632393724@qq.com
  * All Rights Saved! Chongqing AnYun Tech co. LTD
  */
-public class LoginAuthRespHandler extends ChannelInboundHandlerAdapter {
+public class LoginAuthRespHandler extends  ChannelInboundHandlerAdapter {
     
     private static final String TAG = LoginAuthRespHandler.class.getSimpleName();
     private IMSClientInteface imsClient;
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        super.channelActive(ctx);
+        Log.i(TAG, "channelActive: ");
+
+    }
 
     /**
      * 鏋勯�犲嚱鏁�
@@ -36,7 +44,7 @@
     @Override
     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
         super.channelRead(ctx, msg);
-        Log.i(TAG, "channelRead");
+//        Log.i(TAG, "channelRead"+(String)msg);
         // TODO: 2019/12/4  
     }
 }
diff --git a/im_lib/src/main/java/com/anyun/im_lib/MsgDispatcher.java b/im_lib/src/main/java/com/anyun/im_lib/MsgDispatcher.java
index 93da0f0..9fbc31e 100644
--- a/im_lib/src/main/java/com/anyun/im_lib/MsgDispatcher.java
+++ b/im_lib/src/main/java/com/anyun/im_lib/MsgDispatcher.java
@@ -9,7 +9,17 @@
  * All Rights Saved! Chongqing AnYun Tech co. LTD
  */
 public class MsgDispatcher {
-    public void setOnEventListener(OnEventListener listener) {
 
+    private OnEventListener onEventListener;
+
+    public void setOnEventListener(OnEventListener listener) {
+        this.onEventListener = listener;
+    }
+
+    public void receivedMsg(String msg){
+        // TODO: 2019/12/12
+        if (onEventListener != null){
+            onEventListener.dispatchMsg(msg);
+        }
     }
 }
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 2f04a29..9007df3 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
@@ -110,5 +110,6 @@
 
     MsgTimeOutTimerManager getMsgTimeOutTimerManager();
 
-
+//鑾峰彇娉ㄥ唽娑堟伅
+    byte[] getRegisterMessage();
 }
diff --git a/im_lib/src/main/java/com/anyun/im_lib/listener/IMSConnectStatusCallback.java b/im_lib/src/main/java/com/anyun/im_lib/listener/IMSConnectStatusCallback.java
index f6a4f3e..8a5dccc 100644
--- a/im_lib/src/main/java/com/anyun/im_lib/listener/IMSConnectStatusCallback.java
+++ b/im_lib/src/main/java/com/anyun/im_lib/listener/IMSConnectStatusCallback.java
@@ -8,7 +8,7 @@
  */
 public interface IMSConnectStatusCallback {
     /***ims杩炴帴涓�*/
-    void connecting();
+    void onConnecting();
 
     /***ims杩炴帴鎴愬姛**/
     void onConnected();
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 be669eb..ae61ce2 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
@@ -37,6 +37,13 @@
      */
     int getBackgroundHeartbeatInterval();
 
+
+    /**
+     * 鑾峰彇搴旂敤灞傛秷鎭彂閫佺姸鎬佹姤鍛婃秷鎭被鍨�
+     * @return
+     */
+    int getServerSentReportMsgType();
+
     /**
      * 鑾峰彇搴旂敤灞傛秷鎭彂閫佽秴鏃堕噸鍙戞鏁�
      * @return
@@ -48,4 +55,8 @@
      * @return
      */
     int getResendInterval();
+
+    int getReConnectInterval();
+//娉ㄥ唽娑堟伅
+    byte[] getRegisterMessage();
 }
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 3cec3b8..73332d6 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
@@ -12,9 +12,13 @@
 import com.anyun.im_lib.listener.IMSConnectStatusCallback;
 import com.anyun.im_lib.listener.OnEventListener;
 
+import java.nio.ByteBuffer;
 import java.util.Vector;
+import java.util.function.ToDoubleBiFunction;
 
 import io.netty.bootstrap.Bootstrap;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufAllocator;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelOption;
 import io.netty.channel.EventLoopGroup;
@@ -149,72 +153,8 @@
         }
     }
 
-    private class ResetConnectRunnable implements Runnable{
-        private boolean isFirst;
-        public ResetConnectRunnable(boolean isFirst) {
-            this.isFirst = isFirst;
-        }
 
-        @Override
-        public void run() {
-            if (!isFirst){
-                onConnectStatusCallback(IMSConfig.CONNECT_STATE_FAILURE);
-            }
-            try {
-                //閲嶈繛鏃讹紝閲婃斁宸ヤ綔缁勭嚎绋嬫睜锛屼篃灏辨槸鍋滄蹇冭烦
-                loopGroup.destroyWorkLoopGroup();
-                while (!isClosed){
-                    if (!isNetworkAvaliable()){
-                        try {
-                            Thread.sleep(2000);
-                        } catch (InterruptedException e) {
-                            e.printStackTrace();
-                        }
-                        continue;
-                    }
-                    //缃戠粶鍙敤鎵嶈繘琛岃繛鎺�
-                    int status;
-                    if ((status=reConnect()) == IMSConfig.CONNECT_STATE_SUCCESSFUL){
-                        onConnectStatusCallback(status);
-                        //杩炴帴鎴愬姛锛岃皟鍑哄惊鐜�
-                        break;
-                    }
 
-                    if (status == IMSConfig.CONNECT_STATE_FAILURE){
-                        onConnectStatusCallback(status);
-                        try {
-                            Thread.sleep(IMSConfig.DEFAULT_RECONNECT_INTERVAL);
-                        } catch (InterruptedException e) {
-                            e.printStackTrace();
-                        }
-                    }
-                }
-            } finally {
-                //鏍囪瘑閲嶈繛浠诲姟鍋滄
-                isReconnecting = false;
-            }
-        }
-    }
-
-    /**
-     * 閲嶈繛锛岄娆¤繛鎺ヤ篃璁や负鏄涓�娆¢噸杩�
-     * @return
-     */
-    private int reConnect() {
-        if (!isClosed){
-            try {
-                //鍏堥噴鏀綞ventLoop绾跨▼缁�
-                if (bootstrap != null){
-                    bootstrap.group().shutdownGracefully();
-                }
-            } finally {
-                    bootstrap = null;
-            }
-            initBootstrap();
-            return connectServer();
-        }
-        return IMSConfig.CONNECT_STATE_FAILURE;
-    }
 
     /***
      * 鍒濆鍖朆ootstrap
@@ -225,19 +165,29 @@
         bootstrap.group(loopGroup).channel(NioSocketChannel.class);
         // 璁剧疆璇ラ」浠ュ悗锛屽鏋滃湪涓ゅ皬鏃跺唴娌℃湁鏁版嵁閫氫俊鏃讹紝TCP浼氳嚜鍔ㄥ彂閫佷竴涓椿鍔ㄦ帰娴嬫暟鎹姤鏂�
         bootstrap.option(ChannelOption.SO_KEEPALIVE,true);
+        //璁剧疆绂佺敤nagle绠楁硶
+        bootstrap.option(ChannelOption.TCP_NODELAY,true);
         bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS,getConnectTimeout());
         bootstrap.handler(new TCPChannelInitializerHandler(this));
     }
 
-    private int connectServer(){
-        if (serverUrlList == null || serverUrlList.size() == 0){
-            return IMSConfig.CONNECT_STATE_FAILURE;
-        }
-        for (int i = 0; i < serverUrlList.size(); i++) {
-            String serverUrl = serverUrlList.get(i);
-            if (TextUtils.isEmpty(serverUrl)){
-                return IMSConfig.CONNECT_STATE_FAILURE;
+
+    /**
+     * 鐪熸杩炴帴鏈嶅姟鍣ㄧ殑鍦版柟
+     */
+    private void toServer() {
+        try {
+            channel = bootstrap.connect(currentHost,currentPort).sync().channel();
+        } catch (Exception e) {
+            Log.i(TAG, String.format("杩炴帴Server(ip[%s],port[%d]澶辫触)",currentHost,currentPort));
+            try {
+                Thread.sleep(500);
+            } catch (InterruptedException ex) {
+                ex.printStackTrace();
             }
+
+
+            channel = null;
         }
     }
 
@@ -248,9 +198,46 @@
         return false;
     }
 
+    /**
+     * 鍥炶皟ims杩炴帴鐘舵��
+     * @param connectStateConnecting
+     */
     private void onConnectStatusCallback(int connectStateConnecting) {
+        this.connectStatus = connectStateConnecting;
+        switch (connectStatus){
+            case IMSConfig.CONNECT_STATE_CONNECTING:
+                Log.i(TAG, "onConnectStatusCallback: ims杩炴帴涓�...");
+                if (imsConnectStatusCallback != null){
+                    imsConnectStatusCallback.onConnecting();
+                }
+                break;
+            case IMSConfig.CONNECT_STATE_SUCCESSFUL:
+                Log.i(TAG, String.format("onConnectStatusCallback: ims杩炴帴鎴愬姛锛宧ost[%s],port[%s]",currentHost,currentPort));
+                if (imsConnectStatusCallback != null){
+                    imsConnectStatusCallback.onConnected();
+                }
+                // TODO: 2019/12/12  杩炴帴鎴愬姛 锛屽彂閫佹彙鎵嬫秷鎭紙闇�瑕佺殑璇濃�斺�旓級
+                try {
+                    ByteBuf byteBuf = ByteBufAllocator.DEFAULT.ioBuffer();
+                    byteBuf.writeBytes(mOnEventListener.getRegisterMessage());
+                    channel.writeAndFlush(byteBuf);
+                } catch (Exception e) {
+                    Log.i(TAG, "鍙戦�佹秷鎭け璐ワ紝reason="+e.getMessage()+"\t");
+                }
+                break;
+            case IMSConfig.CONNECT_STATE_FAILURE:
+                default:
+                    Log.i(TAG, "onConnectStatusCallback: ims杩炴帴澶辫触");
+                    if (imsConnectStatusCallback != null){
+                        imsConnectStatusCallback.onConnectFailed();
+                    }
+                    break;
+        }
     }
 
+    /**
+     * 鍏抽棴杩炴帴锛屽悓鏃堕噴鏀捐祫婧�
+     */
     @Override
     public void close() {
         if (isClosed){
@@ -323,22 +310,51 @@
 
     @Override
     public void sendMsg(String msg) {
-
+        this.sendMsg(msg,true);
     }
 
+    /**
+     *
+     * @param msg
+     * @param isJoinTimeoutManager 鏄惁鍔犲叆瓒呮椂绠$悊鍣�
+     */
     @Override
     public void sendMsg(String msg, boolean isJoinTimeoutManager) {
+        if (msg==null ){
+            return;
+        }
+        // TODO: 2019/12/12  鏍规嵁MSG_ID 鏉ュ姞鍏� 瓒呮椂锛�  鏆備笉鍐�
 
+        if (channel == null){
+            Log.i(TAG, "sendMsg fail,channel涓虹┖"+msg);
+        }
+        try {
+            ByteBuf byteBuf = ByteBufAllocator.DEFAULT.ioBuffer();
+            byteBuf.writeBytes(msg.getBytes());
+            channel.writeAndFlush(byteBuf);
+        } catch (Exception e) {
+            Log.i(TAG, "鍙戦�佹秷鎭け璐ワ紝reason="+e.getMessage()+"\t"+msg);
+        }
     }
 
+    /**
+     * 鑾峰彇瀹㈡埛璁剧疆鐨勯噸杩炴椂闀�
+     * @return
+     */
     @Override
     public int getReconnectInterval() {
-        return 0;
+        if (mOnEventListener != null && mOnEventListener.getReConnectInterval()>0){
+            return reconnectInterval = mOnEventListener.getReConnectInterval();
+        }
+        return reconnectInterval;
     }
 
     @Override
     public int getConnectTimeout() {
-        return 0;
+        if(mOnEventListener != null && mOnEventListener.getConnectTimeout()>0){
+            connectTimeOut = mOnEventListener.getConnectTimeout();
+        }
+        return connectTimeOut;
     }
 
     @Override
@@ -368,11 +384,139 @@
 
     @Override
     public MsgDispatcher getMsgDispatcher() {
-        return null;
+        return msgDispatcher;
     }
 
     @Override
     public MsgTimeOutTimerManager getMsgTimeOutTimerManager() {
+        return msgTimeOutTimerManager;
+    }
+
+    @Override
+    public byte[] getRegisterMessage() {
+        if (mOnEventListener != null){
+            return mOnEventListener.getRegisterMessage();
+        }
         return null;
     }
+
+
+    /**
+     * 閲嶈繛浠诲姟
+     */
+    private class ResetConnectRunnable implements Runnable{
+        private boolean isFirst;
+        public ResetConnectRunnable(boolean isFirst) {
+            this.isFirst = isFirst;
+        }
+
+        @Override
+        public void run() {
+            Log.i(TAG, "鎵ц閲嶈繛浠诲姟");
+            if (!isFirst){
+                onConnectStatusCallback(IMSConfig.CONNECT_STATE_FAILURE);
+            }
+            try {
+                //閲嶈繛鏃讹紝閲婃斁宸ヤ綔缁勭嚎绋嬫睜锛屼篃灏辨槸鍋滄蹇冭烦
+                loopGroup.destroyWorkLoopGroup();
+                while (!isClosed){
+                    if (!isNetworkAvaliable()){
+                        try {
+                            Thread.sleep(2000);
+                        } catch (InterruptedException e) {
+                            e.printStackTrace();
+                        }
+                        continue;
+                    }
+                    //缃戠粶鍙敤鎵嶈繘琛岃繛鎺�
+                    int status;
+                    if ((status=reConnect()) == IMSConfig.CONNECT_STATE_SUCCESSFUL){
+                        onConnectStatusCallback(status);
+                        //杩炴帴鎴愬姛锛岃皟鍑哄惊鐜�
+                        break;
+                    }
+
+                    if (status == IMSConfig.CONNECT_STATE_FAILURE){
+                        onConnectStatusCallback(status);
+                        try {
+                            Thread.sleep(IMSConfig.DEFAULT_RECONNECT_INTERVAL);
+                        } catch (InterruptedException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
+            } finally {
+                //鏍囪瘑閲嶈繛浠诲姟鍋滄
+                isReconnecting = false;
+            }
+        }
+
+        /**
+         * 閲嶈繛锛岄娆¤繛鎺ヤ篃璁や负鏄涓�娆¢噸杩�
+         * @return
+         */
+        private int reConnect() {
+            if (!isClosed){
+                try {
+                    //鍏堥噴鏀綞ventLoop绾跨▼缁�
+                    if (bootstrap != null){
+                        bootstrap.group().shutdownGracefully();
+                    }
+                } finally {
+                    bootstrap = null;
+                }
+                initBootstrap();
+                return connectServer();
+            }
+            return IMSConfig.CONNECT_STATE_FAILURE;
+        }
+
+        private int connectServer(){
+            //鏈嶅姟鍣ㄥ湴鍧�鏃犳晥锛岀洿鎺ュ洖璋冭繛鎺ョ姸鎬侊紝涓嶅啀杩涜杩炴帴
+            if (serverUrlList == null || serverUrlList.size() == 0){
+                return IMSConfig.CONNECT_STATE_FAILURE;
+            }
+            for (int i = 0; i < serverUrlList.size(); i++) {
+                String serverUrl = serverUrlList.get(i);
+                //鏈嶅姟鍣ㄥ湴鍧�鏃犳晥锛岀洿鎺ュ洖璋冭繛鎺ョ姸鎬侊紝涓嶅啀杩涜杩炴帴
+                if (TextUtils.isEmpty(serverUrl)){
+                    return IMSConfig.CONNECT_STATE_FAILURE;
+                }
+                String[] address = serverUrl.split(" ");
+                for (int j = 1; j <= IMSConfig.DEFAULT_RECONNECT_COUNT; j++) {
+                    //濡傛灉ims宸茬粡鍏抽棴锛屾垨缃戠粶涓嶅彲鐢紝鐩存帴鍥炶皟杩炴帴鐘舵�侊紝涓嶅啀杩涜杩炴帴
+                    if (isClosed || !isNetworkAvaliable()){
+                        return IMSConfig.CONNECT_STATE_FAILURE;
+                    }
+                    //鍥炶皟杩炴帴鐘舵��
+                    if(connectStatus != IMSConfig.CONNECT_STATE_CONNECTING){
+                        onConnectStatusCallback(IMSConfig.CONNECT_STATE_CONNECTING);
+                    }
+                    Log.i(TAG, String.format("姝e湪杩涜connectServer銆�%s銆戠殑绗琜%d]杩炴帴锛屽綋鍓嶉噸杩炲欢鏃舵椂闀夸负[%dms]: ",serverUrl,j,j*getReconnectInterval()));
+                    try {
+                        currentPort = Integer.parseInt(address[1]);
+                        currentHost = address[0];
+                        //杩炴帴鏈嶅姟鍣�
+                        toServer();
+                        //channel涓嶄负绌猴紝鍒欒涓鸿繛鎺ュ凡缁忔垚鍔�
+                        if(channel != null){
+                            return IMSConfig.CONNECT_STATE_SUCCESSFUL;
+                        }else{
+                            Thread.sleep(j*getReconnectInterval());
+                        }
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                        close();
+                        break;
+                    }
+                }
+            }
+            return IMSConfig.CONNECT_STATE_FAILURE;
+        }
+
+    }
+
+
+
+
 }
diff --git a/im_lib/src/main/java/com/anyun/im_lib/netty/TCPChannelInitializerHandler.java b/im_lib/src/main/java/com/anyun/im_lib/netty/TCPChannelInitializerHandler.java
index fe1b127..37f0d28 100644
--- a/im_lib/src/main/java/com/anyun/im_lib/netty/TCPChannelInitializerHandler.java
+++ b/im_lib/src/main/java/com/anyun/im_lib/netty/TCPChannelInitializerHandler.java
@@ -1,12 +1,18 @@
 package com.anyun.im_lib.netty;
 
+import android.util.Log;
+
 import com.anyun.im_lib.HeartbeatRespHandler;
 import com.anyun.im_lib.LoginAuthRespHandler;
 import com.anyun.im_lib.interf.IMSClientInteface;
 
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelInitializer;
 import io.netty.channel.ChannelPipeline;
+import io.netty.handler.codec.DelimiterBasedFrameDecoder;
+
 
 /**
  * MyApplication2
@@ -17,6 +23,8 @@
  */
 public class TCPChannelInitializerHandler  extends ChannelInitializer<Channel> {
 
+    private static final String TAG = TCPChannelInitializerHandler.class.getSimpleName();
+
     private IMSClientInteface imsClient;
 
     public TCPChannelInitializerHandler(NettyTcpClient nettyTcpClient) {
@@ -26,11 +34,40 @@
     @Override
     protected void initChannel(Channel channel) throws Exception {
         ChannelPipeline pipeline = channel.pipeline();
+        Log.i(TAG, "initChannel: ");
 
         //netty鎻愪緵鐨勮嚜瀹氫箟闀垮害瑙g爜鍣紝瑙e喅TP鎷嗗寘/绮樺寘闂
 
         // TODO: 2019/12/4
+//        锛�1锛� maxFrameLength - 鍙戦�佺殑鏁版嵁鍖呮渶澶ч暱搴︼紱
+//
+//锛�2锛� lengthFieldOffset - 闀垮害鍩熷亸绉婚噺锛屾寚鐨勬槸闀垮害鍩熶綅浜庢暣涓暟鎹寘瀛楄妭鏁扮粍涓殑涓嬫爣锛�
+//
+//锛�3锛� lengthFieldLength - 闀垮害鍩熺殑鑷繁鐨勫瓧鑺傛暟闀垮害銆�
+//
+//锛�4锛� lengthAdjustment 鈥� 闀垮害鍩熺殑鍋忕Щ閲忕煫姝c�� 濡傛灉闀垮害鍩熺殑鍊硷紝闄や簡鍖呭惈鏈夋晥鏁版嵁鍩熺殑闀垮害澶栵紝杩樺寘鍚簡鍏朵粬鍩燂紙濡傞暱搴﹀煙鑷韩锛夐暱搴︼紝閭d箞锛屽氨闇�瑕佽繘琛岀煫姝c�傜煫姝g殑鍊间负锛氬寘闀� - 闀垮害鍩熺殑鍊� 鈥� 闀垮害鍩熷亸绉� 鈥� 闀垮害鍩熼暱銆�
+//
+//锛�5锛� initialBytesToStrip 鈥� 涓㈠純鐨勮捣濮嬪瓧鑺傛暟銆備涪寮冨浜庢湁鏁堟暟鎹墠闈㈢殑瀛楄妭鏁伴噺銆傛瘮濡傚墠闈㈡湁4涓妭鐐圭殑闀垮害鍩燂紝鍒欏畠鐨勫�间负4銆�
+//
+//        鍦ㄤ笂闈㈢殑渚嬪瓙涓紝鑷畾涔夐暱搴﹁В鐮佸櫒鐨勬瀯閫犲弬鏁板�煎涓嬶細
+//
+//        LengthFieldBasedFrameDecoder spliter=new LengthFieldBasedFrameDecoder(1024,0,4,0,4);
+//        绗竴涓弬鏁颁负1024锛岃〃绀烘暟鎹寘鐨勬渶澶ч暱搴︿负1024锛�
+//        绗簩涓弬鏁�0锛岃〃绀洪暱搴﹀煙鐨勫亸绉婚噺涓�0锛屼篃灏辨槸闀垮害鍩熸斁鍦ㄤ簡鏈�鍓嶉潰锛屽浜庡寘鐨勮捣濮嬩綅缃紱
+//        绗笁涓弬鏁颁负4锛岃〃绀洪暱搴﹀煙鍗犵敤4涓瓧鑺傦紱
+//        绗洓涓弬鏁颁负0锛岃〃绀洪暱搴﹀煙淇濆瓨鐨勫�硷紝浠呬粎涓烘湁鏁堟暟鎹暱搴︼紝涓嶅寘鍚叾浠栧煙锛堝闀垮害鍩燂級鐨勯暱搴︼紱
+//        绗簲涓弬鏁颁负4锛岃〃绀烘渶缁堢殑鍙栧埌鐨勭洰鏍囨暟鎹寘锛屾姏寮冩渶鍓嶉潰鐨�4涓瓧鑺傛暟鎹紝闀垮害鍩熺殑鍊艰鎶涘純銆�
+//
+//        涓轰簡鏇村姞娓呮鐨勮鏄庝竴涓嬩笂闈㈢殑瑙勫垯锛岃皟鏁翠竴涓嬩緥瀛愪腑鐨勪唬鐮併�傚湪鍐欏叆閫氶亾鍓嶏紝鍦ㄦ暟鎹�
+//        pipeline.addLast(new LengthFieldBasedFrameDecoder(1024,3 ,2,1,0));
 
+//        pipeline.addLast(new FixedLengthFrameDecoder(10));  // 娴嬭瘯鐢�  鍥哄畾闀垮害娑堟伅
+
+//        pipeline.addLast(new LineBasedFrameDecoder(1024));
+
+        byte[] bytes = new byte[]{0x7e};
+        ByteBuf byteBuf = Unpooled.copiedBuffer(bytes);
+        pipeline.addLast(new DelimiterBasedFrameDecoder(1024,byteBuf));
 
         //鎻℃墜璁よ瘉娑堟伅鐩稿簲澶勭悊handler
         pipeline.addLast(LoginAuthRespHandler.class.getSimpleName(), new LoginAuthRespHandler(imsClient));
diff --git a/im_lib/src/main/java/com/anyun/im_lib/netty/TCPReadHandler.java b/im_lib/src/main/java/com/anyun/im_lib/netty/TCPReadHandler.java
index 5f898ed..ad3116d 100644
--- a/im_lib/src/main/java/com/anyun/im_lib/netty/TCPReadHandler.java
+++ b/im_lib/src/main/java/com/anyun/im_lib/netty/TCPReadHandler.java
@@ -3,7 +3,10 @@
 import android.util.Log;
 
 import com.anyun.im_lib.interf.IMSClientInteface;
+import com.anyun.im_lib.util.ByteUtil;
 
+
+import io.netty.buffer.ByteBuf;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
@@ -45,6 +48,7 @@
         Channel channel = ctx.channel();
         if (channel != null){
             channel.close();
+            ctx.close();
         }
         //瑙﹀彂閲嶈繛
         imsClient.resetConnect(false);
@@ -52,14 +56,21 @@
 
     @Override
     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
-        super.channelRead(ctx, msg);
         // TODO: 2019/12/4
+        //鏈嶅姟绔繑鍥炴秷鎭悗
+        ByteBuf buf = (ByteBuf) msg;
+        byte[] req = new byte[buf.readableBytes()];
+        buf.readBytes(req);
+        Log.i(TAG, "channelRead hex str: "+ ByteUtil.byte2HexStr(req));
+        String str = new String(req, "UTF-8");
 
+        imsClient.getMsgDispatcher().receivedMsg(   str  );
     }
 
     @Override
     public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
         super.channelReadComplete(ctx);
         Log.i(TAG, "channelReadComplete");
+
     }
 }
diff --git a/im_lib/src/main/java/com/anyun/im_lib/util/ByteUtil.java b/im_lib/src/main/java/com/anyun/im_lib/util/ByteUtil.java
new file mode 100644
index 0000000..7c93921
--- /dev/null
+++ b/im_lib/src/main/java/com/anyun/im_lib/util/ByteUtil.java
@@ -0,0 +1,209 @@
+package com.anyun.im_lib.util;
+
+import android.text.TextUtils;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+
+/**
+ * MyApplication2
+ * Created by lzw on 2019/12/13. 12:01:18
+ * 閭锛�632393724@qq.com
+ * All Rights Saved! Chongqing AnYun Tech co. LTD
+ */
+public class ByteUtil {
+
+
+    /**
+     * @鍔熻兘: BCD鐮佽浆涓�10杩涘埗涓�(闃挎媺浼暟鎹�)
+     * @鍙傛暟: BCD鐮�
+     * @缁撴灉: 10杩涘埗涓�
+     */
+    public static String bcd2Str(byte[] bytes) {
+        StringBuffer temp = new StringBuffer(bytes.length * 2);
+        for (int i = 0; i < bytes.length; i++) {
+            temp.append((byte) ((bytes[i] & 0xf0) >>> 4));
+            temp.append((byte) (bytes[i] & 0x0f));
+        }
+        return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp
+                .toString().substring(1) : temp.toString();
+    }
+
+    /**
+     * @鍔熻兘: 10杩涘埗涓茶浆涓築CD鐮�
+     * @鍙傛暟: 10杩涘埗涓�
+     * @缁撴灉: BCD鐮�
+     */
+    public static byte[] str2Bcd(String asc) {
+        int len = asc.length();
+        int mod = len % 2;
+        if (mod != 0) {
+            asc = "0" + asc;
+            len = asc.length();
+        }
+        byte abt[] = new byte[len];
+        if (len >= 2) {
+            len = len / 2;
+        }
+        byte bbt[] = new byte[len];
+        abt = asc.getBytes();
+        int j, k;
+        for (int p = 0; p < asc.length() / 2; p++) {
+            if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
+                j = abt[2 * p] - '0';
+            } else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
+                j = abt[2 * p] - 'a' + 0x0a;
+            } else {
+                j = abt[2 * p] - 'A' + 0x0a;
+            }
+            if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
+                k = abt[2 * p + 1] - '0';
+            } else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
+                k = abt[2 * p + 1] - 'a' + 0x0a;
+            } else {
+                k = abt[2 * p + 1] - 'A' + 0x0a;
+            }
+            int a = (j << 4) + k;
+            byte b = (byte) a;
+            bbt[p] = b;
+        }
+        return bbt;
+    }
+
+    public static String getString(byte[] bytes, String charsetName) {
+        return new String(bytes, Charset.forName(charsetName));
+    }
+
+    public static String getString(byte[] bytes) {
+        return getString(bytes, "GBK");
+    }
+
+    /**
+     * bytes杞崲鎴愬崄鍏繘鍒跺瓧绗︿覆
+     * @param byte[] b byte鏁扮粍
+     * @return String 姣忎釜Byte鍊间箣闂寸┖鏍煎垎闅�
+     */
+    public static String byte2HexStr(byte[] b)
+    {
+        String stmp="";
+        StringBuilder sb = new StringBuilder("");
+        for (int n=0;n<b.length;n++)
+        {
+            stmp = Integer.toHexString(b[n] & 0xFF);
+            sb.append((stmp.length()==1)? "0"+stmp : stmp);
+            sb.append(" ");
+        }
+        return sb.toString().toUpperCase().trim();
+    }
+
+    /**
+     * bytes瀛楃涓茶浆鎹负Byte鍊�
+     * @param String src Byte瀛楃涓诧紝姣忎釜Byte涔嬮棿娌℃湁鍒嗛殧绗�
+     * @return byte[]
+     */
+    public static byte[] hexStr2Bytes(String src)
+    {
+        int m=0,n=0;
+        int l=src.length()/2;
+        System.out.println(l);
+        byte[] ret = new byte[l];
+        for (int i = 0; i < l; i++)
+        {
+            m=i*2+1;
+            n=m+1;
+            ret[i] = Byte.decode("0x" + src.substring(i*2, m) + src.substring(m,n));
+        }
+        return ret;
+    }
+
+    /**
+     * 16杩涘埗鐨勫瓧绗︿覆琛ㄧず杞垚瀛楄妭鏁扮粍
+     *
+     * @param hexString 16杩涘埗鏍煎紡鐨勫瓧绗︿覆
+     * @return 杞崲鍚庣殑瀛楄妭鏁扮粍
+     **/
+    public static byte[] toByteArray(String hexString) {
+        if (TextUtils.isEmpty(hexString))
+            throw new IllegalArgumentException("this hexString must not be empty");
+
+        hexString = hexString.toLowerCase();
+        final byte[] byteArray = new byte[hexString.length() / 2];
+        int k = 0;
+        for (int i = 0; i < byteArray.length; i++) {//鍥犱负鏄�16杩涘埗锛屾渶澶氬彧浼氬崰鐢�4浣嶏紝杞崲鎴愬瓧鑺傞渶瑕佷袱涓�16杩涘埗鐨勫瓧绗︼紝楂樹綅鍦ㄥ厛
+            byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
+            byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
+            byteArray[i] = (byte) (high << 4 | low);
+            k += 2;
+        }
+        return byteArray;
+    }
+
+
+    public static int getInt(byte i) {
+        int low = i&0x0f;
+        int hight= (i>>4)&0x0f;
+        return low+hight*16;
+    }
+
+    public static int getBCDInt(byte i) {
+        int low = i&0x0f;
+        int hight= (i>>4)&0x0f;
+        return low+hight*10;
+    }
+
+
+
+
+    /**
+     * ByteBuffer 杞崲 String
+     * @param buffer
+     * @return
+     */
+    public static String getString(ByteBuffer buffer)
+    {
+        Charset charset = null;
+        CharsetDecoder decoder = null;
+        CharBuffer charBuffer = null;
+        try
+        {
+            charset = Charset.forName("UTF-8");
+            decoder = charset.newDecoder();
+             charBuffer = decoder.decode(buffer);//鐢ㄨ繖涓殑璇濓紝鍙兘杈撳嚭鏉ヤ竴娆$粨鏋滐紝绗簩娆℃樉绀轰负绌�
+//            charBuffer = decoder.decode(buffer.asReadOnlyBuffer());
+            return charBuffer.toString();
+        }
+        catch (Exception ex)
+        {
+            ex.printStackTrace();
+            return "";
+        }
+    }
+
+    /**
+     * short杞负瀛楄妭鏁扮粍
+     * @param data
+     * @return 鍖呭惈2涓瓧鑺傜殑瀛楄妭鏁扮粍
+     */
+    public static byte[] shortGetBytes(short data) {
+        byte[] bytes = new byte[2];
+        bytes[0] = (byte) (data & 0xff);
+        bytes[1] = (byte) ((data & 0xff00) >> 8);
+        return bytes;
+    }
+
+    public static  byte[] shortGetByte(short data){
+        byte[] bytes = new byte[1];
+        bytes[0] = (byte)(data & 0xff);
+        return bytes;
+    }
+
+    public static void main(String[] args){
+        System.out.println(byte2HexStr(shortGetBytes((short) 65535)));
+        short b = (short) 32768;
+        b++;
+        System.out.println(byte2HexStr(shortGetBytes((short) b)));
+    }
+
+}
diff --git a/settings.gradle b/settings.gradle
index 3cbe249..c3516ad 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include ':app', ':lib'
+include ':app', ':lib', ':im_lib'

--
Gitblit v1.8.0