Browse Source

remoting 层改造中, 增加mina 开发ing 提交下,备份

hugui 9 years ago
parent
commit
85f23d1b7c
79 changed files with 2738 additions and 1734 deletions
  1. 5 0
      lts-core/pom.xml
  2. 21 14
      lts-core/src/main/java/com/lts/core/cluster/AbstractClientNode.java
  3. 22 8
      lts-core/src/main/java/com/lts/core/cluster/AbstractServerNode.java
  4. 1 1
      lts-core/src/main/java/com/lts/core/logger/jcl/JclLogger.java
  5. 2 5
      lts-core/src/main/java/com/lts/core/remoting/HeartBeatMonitor.java
  6. 17 13
      lts-core/src/main/java/com/lts/core/remoting/RemotingClientDelegate.java
  7. 9 8
      lts-core/src/main/java/com/lts/core/remoting/RemotingServerDelegate.java
  8. 3 3
      lts-core/src/main/java/com/lts/core/support/LoggerName.java
  9. 87 91
      lts-core/src/main/java/com/lts/remoting/AbstractRemoting.java
  10. 399 0
      lts-core/src/main/java/com/lts/remoting/AbstractRemotingClient.java
  11. 157 0
      lts-core/src/main/java/com/lts/remoting/AbstractRemotingServer.java
  12. 2 3
      lts-core/src/main/java/com/lts/remoting/AsyncCallback.java
  13. 24 0
      lts-core/src/main/java/com/lts/remoting/Channel.java
  14. 0 7
      lts-core/src/main/java/com/lts/remoting/ChannelEventListener.java
  15. 17 0
      lts-core/src/main/java/com/lts/remoting/ChannelFuture.java
  16. 10 0
      lts-core/src/main/java/com/lts/remoting/ChannelHandler.java
  17. 11 0
      lts-core/src/main/java/com/lts/remoting/ChannelHandlerListener.java
  18. 12 0
      lts-core/src/main/java/com/lts/remoting/Future.java
  19. 19 0
      lts-core/src/main/java/com/lts/remoting/IdleState.java
  20. 5 9
      lts-core/src/main/java/com/lts/remoting/RemotingClient.java
  21. 3 3
      lts-core/src/main/java/com/lts/remoting/RemotingClientConfig.java
  22. 7 14
      lts-core/src/main/java/com/lts/remoting/RemotingEvent.java
  23. 3 3
      lts-core/src/main/java/com/lts/remoting/RemotingEventType.java
  24. 3 5
      lts-core/src/main/java/com/lts/remoting/RemotingProcessor.java
  25. 5 6
      lts-core/src/main/java/com/lts/remoting/RemotingServer.java
  26. 3 17
      lts-core/src/main/java/com/lts/remoting/RemotingServerConfig.java
  27. 9 27
      lts-core/src/main/java/com/lts/remoting/ResponseFuture.java
  28. 16 0
      lts-core/src/main/java/com/lts/remoting/codec/Codec.java
  29. 105 0
      lts-core/src/main/java/com/lts/remoting/codec/DefaultCodec.java
  30. 0 5
      lts-core/src/main/java/com/lts/remoting/common/Pair.java
  31. 19 3
      lts-core/src/main/java/com/lts/remoting/common/RemotingHelper.java
  32. 0 193
      lts-core/src/main/java/com/lts/remoting/common/RemotingUtil.java
  33. 0 1
      lts-core/src/main/java/com/lts/remoting/common/SemaphoreReleaseOnlyOnce.java
  34. 0 12
      lts-core/src/main/java/com/lts/remoting/common/ServiceThread.java
  35. 75 0
      lts-core/src/main/java/com/lts/remoting/mina/MinaChannel.java
  36. 42 0
      lts-core/src/main/java/com/lts/remoting/mina/MinaChannelFuture.java
  37. 51 0
      lts-core/src/main/java/com/lts/remoting/mina/MinaChannelHandler.java
  38. 90 0
      lts-core/src/main/java/com/lts/remoting/mina/MinaCodecFactory.java
  39. 354 0
      lts-core/src/main/java/com/lts/remoting/mina/MinaLogger.java
  40. 155 0
      lts-core/src/main/java/com/lts/remoting/mina/MinaRemotingClient.java
  41. 157 0
      lts-core/src/main/java/com/lts/remoting/mina/MinaRemotingServer.java
  42. 76 0
      lts-core/src/main/java/com/lts/remoting/netty/NettyChannel.java
  43. 41 0
      lts-core/src/main/java/com/lts/remoting/netty/NettyChannelFuture.java
  44. 42 0
      lts-core/src/main/java/com/lts/remoting/netty/NettyChannelHandler.java
  45. 95 0
      lts-core/src/main/java/com/lts/remoting/netty/NettyCodecFactory.java
  46. 0 47
      lts-core/src/main/java/com/lts/remoting/netty/NettyDecoder.java
  47. 0 37
      lts-core/src/main/java/com/lts/remoting/netty/NettyEncoder.java
  48. 333 0
      lts-core/src/main/java/com/lts/remoting/netty/NettyLogger.java
  49. 72 413
      lts-core/src/main/java/com/lts/remoting/netty/NettyRemotingClient.java
  50. 67 180
      lts-core/src/main/java/com/lts/remoting/netty/NettyRemotingServer.java
  51. 5 150
      lts-core/src/main/java/com/lts/remoting/protocol/RemotingCommand.java
  52. 2 12
      lts-core/src/main/java/com/lts/remoting/protocol/RemotingSerializable.java
  53. 0 12
      lts-core/src/main/java/com/lts/remoting/protocol/protocol.txt
  54. 0 4
      lts-core/src/main/java/com/lts/remoting/util/ReflectionUtils.java
  55. 0 115
      lts-core/src/test/java/com/lts/remoting/JsonTest.java
  56. 0 229
      lts-core/src/test/java/com/lts/remoting/NettyRPCTest.java
  57. 1 1
      lts-example/src/main/java/com/lts/example/api/JobTrackerTest.java
  58. 1 0
      lts-example/src/main/java/com/lts/example/api/TaskTrackerTest.java
  59. 5 5
      lts-jobclient/src/main/java/com/lts/jobclient/JobClient.java
  60. 2 2
      lts-jobclient/src/main/java/com/lts/jobclient/processor/AbstractProcessor.java
  61. 2 2
      lts-jobclient/src/main/java/com/lts/jobclient/processor/JobFinishedProcessor.java
  62. 6 6
      lts-jobclient/src/main/java/com/lts/jobclient/processor/RemotingDispatcher.java
  63. 2 2
      lts-jobtracker/src/main/java/com/lts/jobtracker/JobTracker.java
  64. 2 3
      lts-jobtracker/src/main/java/com/lts/jobtracker/channel/ChannelWrapper.java
  65. 3 3
      lts-jobtracker/src/main/java/com/lts/jobtracker/processor/AbstractRemotingProcessor.java
  66. 3 3
      lts-jobtracker/src/main/java/com/lts/jobtracker/processor/JobBizLogProcessor.java
  67. 6 5
      lts-jobtracker/src/main/java/com/lts/jobtracker/processor/JobFinishedProcessor.java
  68. 3 3
      lts-jobtracker/src/main/java/com/lts/jobtracker/processor/JobPullProcessor.java
  69. 3 3
      lts-jobtracker/src/main/java/com/lts/jobtracker/processor/JobSubmitProcessor.java
  70. 11 12
      lts-jobtracker/src/main/java/com/lts/jobtracker/processor/RemotingDispatcher.java
  71. 3 3
      lts-jobtracker/src/main/java/com/lts/jobtracker/support/ClientNotifier.java
  72. 6 5
      lts-jobtracker/src/main/java/com/lts/jobtracker/support/JobPusher.java
  73. 5 5
      lts-jobtracker/src/main/java/com/lts/jobtracker/support/checker/ExecutingDeadJobChecker.java
  74. 2 2
      lts-tasktracker/src/main/java/com/lts/tasktracker/TaskTracker.java
  75. 3 3
      lts-tasktracker/src/main/java/com/lts/tasktracker/logger/BizLoggerImpl.java
  76. 2 2
      lts-tasktracker/src/main/java/com/lts/tasktracker/processor/AbstractProcessor.java
  77. 2 2
      lts-tasktracker/src/main/java/com/lts/tasktracker/processor/JobAskProcessor.java
  78. 5 5
      lts-tasktracker/src/main/java/com/lts/tasktracker/processor/JobPushProcessor.java
  79. 7 7
      lts-tasktracker/src/main/java/com/lts/tasktracker/processor/RemotingDispatcher.java

+ 5 - 0
lts-core/pom.xml

@@ -104,5 +104,10 @@
             <artifactId>h2</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.mina</groupId>
+            <artifactId>mina-core</artifactId>
+            <version>2.0.9</version>
+        </dependency>
     </dependencies>
 </project>

+ 21 - 14
lts-core/src/main/java/com/lts/core/cluster/AbstractClientNode.java

@@ -5,15 +5,17 @@ import com.lts.core.constant.Constants;
 import com.lts.core.factory.NamedThreadFactory;
 import com.lts.core.remoting.HeartBeatMonitor;
 import com.lts.core.remoting.RemotingClientDelegate;
-import com.lts.remoting.netty.NettyClientConfig;
+import com.lts.remoting.RemotingClient;
+import com.lts.remoting.RemotingClientConfig;
+import com.lts.remoting.RemotingProcessor;
+import com.lts.remoting.mina.MinaRemotingClient;
 import com.lts.remoting.netty.NettyRemotingClient;
-import com.lts.remoting.netty.NettyRequestProcessor;
 
 import java.util.concurrent.Executors;
 
 /**
  * @author Robert HG (254963746@qq.com) on 8/18/14.
- *         抽象 netty 客户端
+ *         抽象客户端
  */
 public abstract class AbstractClientNode<T extends Node, App extends Application> extends AbstractJobNode<T, App> {
 
@@ -24,7 +26,7 @@ public abstract class AbstractClientNode<T extends Node, App extends Application
         remotingClient.start();
         heartBeatMonitor.start();
 
-        NettyRequestProcessor defaultProcessor = getDefaultProcessor();
+        RemotingProcessor defaultProcessor = getDefaultProcessor();
         if (defaultProcessor != null) {
             int processorSize = config.getParameter(Constants.PROCESSOR_THREAD, Constants.DEFAULT_PROCESSOR_THREAD);
             remotingClient.registerDefaultProcessor(defaultProcessor,
@@ -36,7 +38,7 @@ public abstract class AbstractClientNode<T extends Node, App extends Application
     /**
      * 得到默认的处理器
      */
-    protected abstract NettyRequestProcessor getDefaultProcessor();
+    protected abstract RemotingProcessor getDefaultProcessor();
 
     protected void remotingStop() {
         heartBeatMonitor.stop();
@@ -54,14 +56,6 @@ public abstract class AbstractClientNode<T extends Node, App extends Application
         return remotingClient.isServerEnable();
     }
 
-    /**
-     * 这个子类可以覆盖
-     */
-    protected NettyClientConfig getNettyClientConfig() {
-        NettyClientConfig config = new NettyClientConfig();
-        return config;
-    }
-
     /**
      * 设置连接JobTracker的负载均衡算法
      *
@@ -75,12 +69,22 @@ public abstract class AbstractClientNode<T extends Node, App extends Application
     @Override
     protected void beforeRemotingStart() {
         //
-        this.remotingClient = new RemotingClientDelegate(new NettyRemotingClient(getNettyClientConfig()), application);
+        this.remotingClient = new RemotingClientDelegate(getRemotingClient(new RemotingClientConfig()), application);
         this.heartBeatMonitor = new HeartBeatMonitor(remotingClient, application);
 
         beforeStart();
     }
 
+    private RemotingClient getRemotingClient(RemotingClientConfig remotingClientConfig) {
+        String remotingType = config.getParameter("lts.remoting", "netty");
+        if ("mina".equals(remotingType)) {
+            return new MinaRemotingClient(remotingClientConfig);
+        } else {
+            return new NettyRemotingClient(remotingClientConfig);
+        }
+    }
+
+
     @Override
     protected void afterRemotingStart() {
         // 父类要做的
@@ -98,8 +102,11 @@ public abstract class AbstractClientNode<T extends Node, App extends Application
     }
 
     protected abstract void beforeStart();
+
     protected abstract void afterStart();
+
     protected abstract void afterStop();
+
     protected abstract void beforeStop();
 
 }

+ 22 - 8
lts-core/src/main/java/com/lts/core/cluster/AbstractServerNode.java

@@ -4,15 +4,17 @@ import com.lts.core.Application;
 import com.lts.core.constant.Constants;
 import com.lts.core.factory.NamedThreadFactory;
 import com.lts.core.remoting.RemotingServerDelegate;
+import com.lts.remoting.RemotingServer;
+import com.lts.remoting.RemotingServerConfig;
+import com.lts.remoting.RemotingProcessor;
+import com.lts.remoting.mina.MinaRemotingServer;
 import com.lts.remoting.netty.NettyRemotingServer;
-import com.lts.remoting.netty.NettyRequestProcessor;
-import com.lts.remoting.netty.NettyServerConfig;
 
 import java.util.concurrent.Executors;
 
 /**
  * @author Robert HG (254963746@qq.com) on 8/18/14.
- *         抽象 netty 服务端
+ *         抽象服务端
  */
 public abstract class AbstractServerNode<T extends Node, App extends Application> extends AbstractJobNode<T, App> {
 
@@ -22,7 +24,7 @@ public abstract class AbstractServerNode<T extends Node, App extends Application
 
         remotingServer.start();
 
-        NettyRequestProcessor defaultProcessor = getDefaultProcessor();
+        RemotingProcessor defaultProcessor = getDefaultProcessor();
         if (defaultProcessor != null) {
             int processorSize = config.getParameter(Constants.PROCESSOR_THREAD, Constants.DEFAULT_PROCESSOR_THREAD);
             remotingServer.registerDefaultProcessor(defaultProcessor,
@@ -40,19 +42,28 @@ public abstract class AbstractServerNode<T extends Node, App extends Application
 
     @Override
     protected void beforeRemotingStart() {
-        NettyServerConfig nettyServerConfig = new NettyServerConfig();
+        RemotingServerConfig remotingServerConfig = new RemotingServerConfig();
         // config 配置
         if (config.getListenPort() == 0) {
             config.setListenPort(Constants.JOB_TRACKER_DEFAULT_LISTEN_PORT);
             node.setPort(config.getListenPort());
         }
-        nettyServerConfig.setListenPort(config.getListenPort());
+        remotingServerConfig.setListenPort(config.getListenPort());
 
-        remotingServer = new RemotingServerDelegate(new NettyRemotingServer(nettyServerConfig), application);
+        remotingServer = new RemotingServerDelegate(getRemotingServer(remotingServerConfig), application);
 
         beforeStart();
     }
 
+    private RemotingServer getRemotingServer(RemotingServerConfig remotingServerConfig) {
+        String remotingType = config.getParameter("lts.remoting", "netty");
+        if ("mina".equals(remotingType)) {
+            return new MinaRemotingServer(remotingServerConfig);
+        } else {
+            return new NettyRemotingServer(remotingServerConfig);
+        }
+    }
+
     @Override
     protected void afterRemotingStart() {
         afterStart();
@@ -71,11 +82,14 @@ public abstract class AbstractServerNode<T extends Node, App extends Application
     /**
      * 得到默认的处理器
      */
-    protected abstract NettyRequestProcessor getDefaultProcessor();
+    protected abstract RemotingProcessor getDefaultProcessor();
 
     protected abstract void beforeStart();
+
     protected abstract void afterStart();
+
     protected abstract void afterStop();
+
     protected abstract void beforeStop();
 
 

+ 1 - 1
lts-core/src/main/java/com/lts/core/logger/jcl/JclLogger.java

@@ -19,7 +19,7 @@ public class JclLogger extends AbstractLogger implements Logger, Serializable {
 		this.logger = logger;
 	}
 
-    public void trace(String msg) {
+	public void trace(String msg) {
         logger.trace(msg);
     }
 

+ 2 - 5
lts-core/src/main/java/com/lts/core/remoting/HeartBeatMonitor.java

@@ -164,7 +164,7 @@ public class HeartBeatMonitor {
                 }
             }
         } catch (Throwable t) {
-            LOGGER.error(t.getMessage(), t);
+            LOGGER.error("Ping JobTracker error", t);
         }
     }
 
@@ -197,9 +197,6 @@ public class HeartBeatMonitor {
 
     /**
      * 发送心跳
-     *
-     * @param remotingClient
-     * @param addr
      */
     private boolean beat(RemotingClientDelegate remotingClient, String addr) {
 
@@ -208,7 +205,7 @@ public class HeartBeatMonitor {
         RemotingCommand request = RemotingCommand.createRequestCommand(
                 JobProtos.RequestCode.HEART_BEAT.code(), commandBody);
         try {
-            RemotingCommand response = remotingClient.getNettyClient().invokeSync(addr, request, 5000);
+            RemotingCommand response = remotingClient.getRemotingClient().invokeSync(addr, request, 5000);
             if (response != null && JobProtos.ResponseCode.HEART_BEAT_SUCCESS ==
                     JobProtos.ResponseCode.valueOf(response.getCode())) {
                 if (LOGGER.isDebugEnabled()) {

+ 17 - 13
lts-core/src/main/java/com/lts/core/remoting/RemotingClientDelegate.java

@@ -9,9 +9,10 @@ import com.lts.core.loadbalance.LoadBalance;
 import com.lts.core.logger.Logger;
 import com.lts.core.logger.LoggerFactory;
 import com.lts.ec.EventInfo;
-import com.lts.remoting.InvokeCallback;
-import com.lts.remoting.netty.NettyRemotingClient;
-import com.lts.remoting.netty.NettyRequestProcessor;
+import com.lts.remoting.AsyncCallback;
+import com.lts.remoting.RemotingClient;
+import com.lts.remoting.RemotingProcessor;
+import com.lts.remoting.exception.RemotingException;
 import com.lts.remoting.protocol.RemotingCommand;
 
 import java.util.List;
@@ -20,13 +21,12 @@ import java.util.concurrent.ExecutorService;
 
 /**
  * @author Robert HG (254963746@qq.com) on 8/1/14.
- *         JobRemotingClient 包装了 NettyRemotingClient
  */
 public class RemotingClientDelegate {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(RemotingClientDelegate.class);
 
-    private NettyRemotingClient remotingClient;
+    private RemotingClient remotingClient;
     // 连JobTracker的负载均衡算法
     private LoadBalance loadBalance;
     private Application application;
@@ -35,7 +35,7 @@ public class RemotingClientDelegate {
     private volatile boolean serverEnable = false;
     private List<Node> jobTrackers;
 
-    public RemotingClientDelegate(NettyRemotingClient remotingClient, Application application) {
+    public RemotingClientDelegate(RemotingClient remotingClient, Application application) {
         this.remotingClient = remotingClient;
         this.application = application;
         this.loadBalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getAdaptiveExtension();
@@ -59,7 +59,11 @@ public class RemotingClientDelegate {
     }
 
     public void start() {
-        remotingClient.start();
+        try {
+            remotingClient.start();
+        } catch (RemotingException e) {
+            throw new RuntimeException(e);
+        }
     }
 
     public boolean contains(Node jobTracker) {
@@ -105,14 +109,14 @@ public class RemotingClientDelegate {
     /**
      * 异步调用
      */
-    public void invokeAsync(RemotingCommand request, InvokeCallback invokeCallback)
+    public void invokeAsync(RemotingCommand request, AsyncCallback asyncCallback)
             throws JobTrackerNotFoundException {
 
         Node jobTracker = getJobTrackerNode();
 
         try {
             remotingClient.invokeAsync(jobTracker.getAddress(), request,
-                    application.getConfig().getInvokeTimeoutMillis(), invokeCallback);
+                    application.getConfig().getInvokeTimeoutMillis(), asyncCallback);
             this.serverEnable = true;
         } catch (Throwable e) {
             // 将这个JobTracker移除
@@ -123,7 +127,7 @@ public class RemotingClientDelegate {
                 LOGGER.error(e1.getMessage(), e1);
             }
             // 只要不是节点 不可用, 轮询所有节点请求
-            invokeAsync(request, invokeCallback);
+            invokeAsync(request, asyncCallback);
         }
     }
 
@@ -152,12 +156,12 @@ public class RemotingClientDelegate {
         }
     }
 
-    public void registerProcessor(int requestCode, NettyRequestProcessor processor,
+    public void registerProcessor(int requestCode, RemotingProcessor processor,
                                   ExecutorService executor) {
         remotingClient.registerProcessor(requestCode, processor, executor);
     }
 
-    public void registerDefaultProcessor(NettyRequestProcessor processor, ExecutorService executor) {
+    public void registerDefaultProcessor(RemotingProcessor processor, ExecutorService executor) {
         remotingClient.registerDefaultProcessor(processor, executor);
     }
 
@@ -173,7 +177,7 @@ public class RemotingClientDelegate {
         remotingClient.shutdown();
     }
 
-    public NettyRemotingClient getNettyClient() {
+    public RemotingClient getRemotingClient() {
         return remotingClient;
     }
 }

+ 9 - 8
lts-core/src/main/java/com/lts/core/remoting/RemotingServerDelegate.java

@@ -2,11 +2,12 @@ package com.lts.core.remoting;
 
 import com.lts.core.Application;
 import com.lts.core.exception.RemotingSendException;
-import com.lts.remoting.InvokeCallback;
+import com.lts.remoting.Channel;
+import com.lts.remoting.AsyncCallback;
 import com.lts.remoting.RemotingServer;
-import com.lts.remoting.netty.NettyRequestProcessor;
+import com.lts.remoting.RemotingProcessor;
+import com.lts.remoting.exception.RemotingException;
 import com.lts.remoting.protocol.RemotingCommand;
-import io.netty.channel.Channel;
 
 import java.util.concurrent.ExecutorService;
 
@@ -27,17 +28,17 @@ public class RemotingServerDelegate {
     public void start() {
         try {
             remotingServer.start();
-        } catch (InterruptedException e) {
+        } catch (RemotingException e) {
             throw new RuntimeException(e);
         }
     }
 
-    public void registerProcessor(int requestCode, NettyRequestProcessor processor,
+    public void registerProcessor(int requestCode, RemotingProcessor processor,
                                   ExecutorService executor) {
         remotingServer.registerProcessor(requestCode, processor, executor);
     }
 
-    public void registerDefaultProcessor(NettyRequestProcessor processor, ExecutorService executor) {
+    public void registerDefaultProcessor(RemotingProcessor processor, ExecutorService executor) {
         remotingServer.registerDefaultProcessor(processor, executor);
     }
 
@@ -52,12 +53,12 @@ public class RemotingServerDelegate {
         }
     }
 
-    public void invokeAsync(Channel channel, RemotingCommand request, InvokeCallback invokeCallback)
+    public void invokeAsync(Channel channel, RemotingCommand request, AsyncCallback asyncCallback)
             throws RemotingSendException {
         try {
 
             remotingServer.invokeAsync(channel, request,
-                    application.getConfig().getInvokeTimeoutMillis(), invokeCallback);
+                    application.getConfig().getInvokeTimeoutMillis(), asyncCallback);
         } catch (Throwable t) {
             throw new RemotingSendException(t);
         }

+ 3 - 3
lts-core/src/main/java/com/lts/core/support/LoggerName.java

@@ -5,10 +5,10 @@ package com.lts.core.support;
  */
 public interface LoggerName {
 
-    public static final String TaskTracker = "LTS.TaskTracker";
+    public static final String TaskTracker = "LtsTaskTracker";
 
-    public static final String JobClient = "LTS.JobClient";
+    public static final String JobClient = "LtsJobClient";
 
-    public static final String JobTracker = "LTS.JobTracker";
+    public static final String JobTracker = "LtsJobTracker";
 
 }

+ 87 - 91
lts-core/src/main/java/com/lts/remoting/netty/NettyRemotingAbstract.java → lts-core/src/main/java/com/lts/remoting/AbstractRemoting.java

@@ -1,10 +1,10 @@
-package com.lts.remoting.netty;
+package com.lts.remoting;
 
 import com.lts.core.logger.Logger;
 import com.lts.core.logger.LoggerFactory;
 import com.lts.core.support.SystemClock;
-import com.lts.remoting.ChannelEventListener;
-import com.lts.remoting.InvokeCallback;
+import com.lts.remoting.codec.Codec;
+import com.lts.remoting.codec.DefaultCodec;
 import com.lts.remoting.common.Pair;
 import com.lts.remoting.common.RemotingHelper;
 import com.lts.remoting.common.SemaphoreReleaseOnlyOnce;
@@ -14,11 +14,6 @@ import com.lts.remoting.exception.RemotingTimeoutException;
 import com.lts.remoting.exception.RemotingTooMuchRequestException;
 import com.lts.remoting.protocol.RemotingCommand;
 import com.lts.remoting.protocol.RemotingProtos;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelFutureListener;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.timeout.IdleState;
 
 import java.util.HashMap;
 import java.util.Iterator;
@@ -29,40 +24,40 @@ import java.util.concurrent.*;
 /**
  * Server与Client公用抽象类
  */
-public abstract class NettyRemotingAbstract {
-    private static final Logger plog = LoggerFactory.getLogger(RemotingHelper.RemotingLogName);
+public abstract class AbstractRemoting {
+    private static final Logger LOGGER = LoggerFactory.getLogger(RemotingHelper.RemotingLogName);
 
-    // 信号量,Oneway情况会使用,防止本地Netty缓存请求过多
+    // 信号量,Oneway情况会使用,防止本地缓存请求过多
     protected final Semaphore semaphoreOneway;
 
-    // 信号量,异步调用情况会使用,防止本地Netty缓存请求过多
+    // 信号量,异步调用情况会使用,防止本地缓存请求过多
     protected final Semaphore semaphoreAsync;
 
     // 缓存所有对外请求
     protected final ConcurrentHashMap<Integer /* opaque */, ResponseFuture> responseTable =
             new ConcurrentHashMap<Integer, ResponseFuture>(256);
     // 注册的各个RPC处理器
-    protected final HashMap<Integer/* request code */, Pair<NettyRequestProcessor, ExecutorService>> processorTable =
-            new HashMap<Integer, Pair<NettyRequestProcessor, ExecutorService>>(64);
-    protected final NettyEventExecutor nettyEventExecutor = new NettyEventExecutor();
+    protected final HashMap<Integer/* request code */, Pair<RemotingProcessor, ExecutorService>> processorTable =
+            new HashMap<Integer, Pair<RemotingProcessor, ExecutorService>>(64);
+    protected final RemotingEventExecutor remotingEventExecutor = new RemotingEventExecutor();
     // 默认请求代码处理器
-    protected Pair<NettyRequestProcessor, ExecutorService> defaultRequestProcessor;
+    protected Pair<RemotingProcessor, ExecutorService> defaultRequestProcessor;
 
 
-    public NettyRemotingAbstract(final int permitsOneway, final int permitsAsync) {
+    public AbstractRemoting(final int permitsOneway, final int permitsAsync) {
         this.semaphoreOneway = new Semaphore(permitsOneway, true);
         this.semaphoreAsync = new Semaphore(permitsAsync, true);
     }
 
     public abstract ChannelEventListener getChannelEventListener();
 
-    public void putNettyEvent(final NettyEvent event) {
-        this.nettyEventExecutor.putNettyEvent(event);
+    public void putRemotingEvent(final RemotingEvent event) {
+        this.remotingEventExecutor.putRemotingEvent(event);
     }
 
-    public void processRequestCommand(final ChannelHandlerContext ctx, final RemotingCommand cmd) {
-        final Pair<NettyRequestProcessor, ExecutorService> matched = this.processorTable.get(cmd.getCode());
-        final Pair<NettyRequestProcessor, ExecutorService> pair =
+    public void processRequestCommand(final Channel channel, final RemotingCommand cmd) {
+        final Pair<RemotingProcessor, ExecutorService> matched = this.processorTable.get(cmd.getCode());
+        final Pair<RemotingProcessor, ExecutorService> pair =
                 null == matched ? this.defaultRequestProcessor : matched;
 
         if (pair != null) {
@@ -70,42 +65,42 @@ public abstract class NettyRemotingAbstract {
                 @Override
                 public void run() {
                     try {
-                        final RemotingCommand response = pair.getObject1().processRequest(ctx, cmd);
+                        final RemotingCommand response = pair.getObject1().processRequest(channel, cmd);
                         // Oneway形式忽略应答结果
                         if (!cmd.isOnewayRPC()) {
                             if (response != null) {
                                 response.setOpaque(cmd.getOpaque());
                                 response.markResponseType();
                                 try {
-                                    ctx.writeAndFlush(response).addListener(new ChannelFutureListener() {
+                                    channel.writeAndFlush(response).addListener(new ChannelHandlerListener() {
                                         @Override
-                                        public void operationComplete(ChannelFuture future) throws Exception {
+                                        public void operationComplete(Future future) throws Exception {
                                             if (!future.isSuccess()) {
-                                                plog.error("response to " + RemotingHelper.parseChannelRemoteAddr(future.channel()) + " failed", future.cause());
-                                                plog.error(cmd.toString());
-                                                plog.error(response.toString());
+                                                LOGGER.error("response to " + RemotingHelper.parseChannelRemoteAddr(channel) + " failed", future.cause());
+                                                LOGGER.error(cmd.toString());
+                                                LOGGER.error(response.toString());
                                             }
                                         }
                                     });
                                 } catch (Exception e) {
-                                    plog.error("process request over, but response failed", e);
-                                    plog.error(cmd.toString());
-                                    plog.error(response.toString());
+                                    LOGGER.error("process request over, but response failed", e);
+                                    LOGGER.error(cmd.toString());
+                                    LOGGER.error(response.toString());
                                 }
                             } else {
                                 // 收到请求,但是没有返回应答,可能是processRequest中进行了应答,忽略这种情况
                             }
                         }
                     } catch (Exception e) {
-                        plog.error("process request exception", e);
-                        plog.error(cmd.toString());
+                        LOGGER.error("process request exception", e);
+                        LOGGER.error(cmd.toString());
 
                         if (!cmd.isOnewayRPC()) {
                             final RemotingCommand response =
                                     RemotingCommand.createResponseCommand(RemotingProtos.ResponseCode.SYSTEM_ERROR.code(),//
                                             RemotingHelper.exceptionSimpleDesc(e));
                             response.setOpaque(cmd.getOpaque());
-                            ctx.writeAndFlush(response);
+                            channel.writeAndFlush(response);
                         }
                     }
                 }
@@ -115,7 +110,7 @@ public abstract class NettyRemotingAbstract {
                 // 这里需要做流控,要求线程池对应的队列必须是有大小限制的
                 pair.getObject2().submit(run);
             } catch (RejectedExecutionException e) {
-                plog.warn(RemotingHelper.parseChannelRemoteAddr(ctx.channel()) //
+                LOGGER.warn(RemotingHelper.parseChannelRemoteAddr(channel) //
                         + ", too many requests and system thread pool busy, RejectedExecutionException " //
                         + pair.getObject2().toString() //
                         + " request code: " + cmd.getCode());
@@ -124,7 +119,7 @@ public abstract class NettyRemotingAbstract {
                             RemotingCommand.createResponseCommand(RemotingProtos.ResponseCode.SYSTEM_BUSY.code(),
                                     "too many requests and system thread pool busy, please try another server");
                     response.setOpaque(cmd.getOpaque());
-                    ctx.writeAndFlush(response);
+                    channel.writeAndFlush(response);
                 }
             }
         } else {
@@ -133,12 +128,12 @@ public abstract class NettyRemotingAbstract {
                     RemotingCommand.createResponseCommand(RemotingProtos.ResponseCode.REQUEST_CODE_NOT_SUPPORTED.code(),
                             error);
             response.setOpaque(cmd.getOpaque());
-            ctx.writeAndFlush(response);
-            plog.error(RemotingHelper.parseChannelRemoteAddr(ctx.channel()) + error);
+            channel.writeAndFlush(response);
+            LOGGER.error(RemotingHelper.parseChannelRemoteAddr(channel) + error);
         }
     }
 
-    public void processResponseCommand(ChannelHandlerContext ctx, RemotingCommand cmd) {
+    public void processResponseCommand(Channel channel, RemotingCommand cmd) {
         final ResponseFuture responseFuture = responseTable.get(cmd.getOpaque());
         if (responseFuture != null) {
             responseFuture.setResponseCommand(cmd);
@@ -146,7 +141,7 @@ public abstract class NettyRemotingAbstract {
             responseFuture.release();
 
             // 异步调用
-            if (responseFuture.getInvokeCallback() != null) {
+            if (responseFuture.getAsyncCallback() != null) {
                 boolean runInThisThread = false;
                 ExecutorService executor = this.getCallbackExecutor();
                 if (executor != null) {
@@ -157,13 +152,13 @@ public abstract class NettyRemotingAbstract {
                                 try {
                                     responseFuture.executeInvokeCallback();
                                 } catch (Exception e) {
-                                    plog.warn("excute callback in executor exception, and callback throw", e);
+                                    LOGGER.warn("excute callback in executor exception, and callback throw", e);
                                 }
                             }
                         });
                     } catch (Exception e) {
                         runInThisThread = true;
-                        plog.warn("excute callback in executor exception, maybe executor busy", e);
+                        LOGGER.warn("excute callback in executor exception, maybe executor busy", e);
                     }
                 } else {
                     runInThisThread = true;
@@ -173,7 +168,7 @@ public abstract class NettyRemotingAbstract {
                     try {
                         responseFuture.executeInvokeCallback();
                     } catch (Exception e) {
-                        plog.warn("", e);
+                        LOGGER.warn("", e);
                     }
                 }
             }
@@ -182,23 +177,23 @@ public abstract class NettyRemotingAbstract {
                 responseFuture.putResponse(cmd);
             }
         } else {
-            plog.warn("receive response, but not matched any request, "
-                    + RemotingHelper.parseChannelRemoteAddr(ctx.channel()));
-            plog.warn(cmd.toString());
+            LOGGER.warn("receive response, but not matched any request, "
+                    + RemotingHelper.parseChannelRemoteAddr(channel));
+            LOGGER.warn(cmd.toString());
         }
 
         responseTable.remove(cmd.getOpaque());
     }
 
-    public void processMessageReceived(ChannelHandlerContext ctx, RemotingCommand msg) throws Exception {
+    public void processMessageReceived(Channel channel, RemotingCommand msg) throws Exception {
         final RemotingCommand cmd = msg;
         if (cmd != null) {
             switch (cmd.getType()) {
                 case REQUEST_COMMAND:
-                    processRequestCommand(ctx, cmd);
+                    processRequestCommand(channel, cmd);
                     break;
                 case RESPONSE_COMMAND:
-                    processResponseCommand(ctx, cmd);
+                    processResponseCommand(channel, cmd);
                     break;
                 default:
                     break;
@@ -206,7 +201,7 @@ public abstract class NettyRemotingAbstract {
         }
     }
 
-    abstract public ExecutorService getCallbackExecutor();
+    protected abstract ExecutorService getCallbackExecutor();
 
     public void scanResponseTable() {
         Iterator<Entry<Integer, ResponseFuture>> it = this.responseTable.entrySet().iterator();
@@ -220,10 +215,10 @@ public abstract class NettyRemotingAbstract {
                 try {
                     rep.executeInvokeCallback();
                 } catch (Exception e) {
-                    plog.error("scanResponseTable, operationComplete exception", e);
+                    LOGGER.error("scanResponseTable, operationComplete exception", e);
                 }
 
-                plog.warn("remove timeout request, " + rep);
+                LOGGER.warn("remove timeout request, " + rep);
             }
         }
     }
@@ -235,10 +230,10 @@ public abstract class NettyRemotingAbstract {
             final ResponseFuture responseFuture =
                     new ResponseFuture(request.getOpaque(), timeoutMillis, null, null);
             this.responseTable.put(request.getOpaque(), responseFuture);
-            channel.writeAndFlush(request).addListener(new ChannelFutureListener() {
+            channel.writeAndFlush(request).addListener(new ChannelHandlerListener() {
                 @Override
-                public void operationComplete(ChannelFuture f) throws Exception {
-                    if (f.isSuccess()) {
+                public void operationComplete(Future future) throws Exception {
+                    if (future.isSuccess()) {
                         responseFuture.setSendRequestOK(true);
                         return;
                     } else {
@@ -246,10 +241,10 @@ public abstract class NettyRemotingAbstract {
                     }
 
                     responseTable.remove(request.getOpaque());
-                    responseFuture.setCause(f.cause());
+                    responseFuture.setCause(future.cause());
                     responseFuture.putResponse(null);
-                    plog.warn("send a request command to channel <" + channel.remoteAddress() + "> failed.");
-                    plog.warn(request.toString());
+                    LOGGER.warn("send a request command to channel <" + channel.remoteAddress() + "> failed.");
+                    LOGGER.warn(request.toString());
                 }
             });
 
@@ -274,20 +269,20 @@ public abstract class NettyRemotingAbstract {
     }
 
     public void invokeAsyncImpl(final Channel channel, final RemotingCommand request,
-                                final long timeoutMillis, final InvokeCallback invokeCallback) throws InterruptedException,
+                                final long timeoutMillis, final AsyncCallback asyncCallback) throws InterruptedException,
             RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException {
         boolean acquired = this.semaphoreAsync.tryAcquire(timeoutMillis, TimeUnit.MILLISECONDS);
         if (acquired) {
             final SemaphoreReleaseOnlyOnce once = new SemaphoreReleaseOnlyOnce(this.semaphoreAsync);
 
             final ResponseFuture responseFuture =
-                    new ResponseFuture(request.getOpaque(), timeoutMillis, invokeCallback, once);
+                    new ResponseFuture(request.getOpaque(), timeoutMillis, asyncCallback, once);
             this.responseTable.put(request.getOpaque(), responseFuture);
             try {
-                channel.writeAndFlush(request).addListener(new ChannelFutureListener() {
+                channel.writeAndFlush(request).addListener(new ChannelHandlerListener() {
                     @Override
-                    public void operationComplete(ChannelFuture f) throws Exception {
-                        if (f.isSuccess()) {
+                    public void operationComplete(Future future) throws Exception {
+                        if (future.isSuccess()) {
                             responseFuture.setSendRequestOK(true);
                             return;
                         } else {
@@ -298,23 +293,22 @@ public abstract class NettyRemotingAbstract {
                         responseFuture.executeInvokeCallback();
 
                         responseTable.remove(request.getOpaque());
-                        plog.warn("send a request command to channel <" + channel.remoteAddress() + "> failed.");
-                        plog.warn(request.toString());
-
+                        LOGGER.warn("send a request command to channel <" + channel.remoteAddress() + "> failed.");
+                        LOGGER.warn(request.toString());
                     }
                 });
             } catch (Exception e) {
                 once.release();
-                plog.warn("write send a request command to channel <" + channel.remoteAddress() + "> failed.");
+                LOGGER.warn("write send a request command to channel <" + channel.remoteAddress() + "> failed.");
                 throw new RemotingSendRequestException(RemotingHelper.parseChannelRemoteAddr(channel), e);
             }
         } else {
             if (timeoutMillis <= 0) {
                 throw new RemotingTooMuchRequestException("invokeAsyncImpl invoke too fast");
             } else {
-                plog.warn("invokeAsyncImpl tryAcquire semaphore timeout, " + timeoutMillis
+                LOGGER.warn("invokeAsyncImpl tryAcquire semaphore timeout, " + timeoutMillis
                         + " waiting thread nums: " + this.semaphoreAsync.getQueueLength());
-                plog.warn(request.toString());
+                LOGGER.warn(request.toString());
 
                 throw new RemotingTimeoutException("tryAcquire timeout(ms) " + timeoutMillis);
             }
@@ -329,59 +323,59 @@ public abstract class NettyRemotingAbstract {
         if (acquired) {
             final SemaphoreReleaseOnlyOnce once = new SemaphoreReleaseOnlyOnce(this.semaphoreOneway);
             try {
-                channel.writeAndFlush(request).addListener(new ChannelFutureListener() {
+                channel.writeAndFlush(request).addListener(new ChannelHandlerListener() {
                     @Override
-                    public void operationComplete(ChannelFuture f) throws Exception {
+                    public void operationComplete(Future future) throws Exception {
                         once.release();
-                        if (!f.isSuccess()) {
-                            plog.warn("send a request command to channel <" + channel.remoteAddress()
+                        if (!future.isSuccess()) {
+                            LOGGER.warn("send a request command to channel <" + channel.remoteAddress()
                                     + "> failed.");
-                            plog.warn(request.toString());
+                            LOGGER.warn(request.toString());
                         }
                     }
                 });
             } catch (Exception e) {
                 once.release();
-                plog.warn("write send a request command to channel <" + channel.remoteAddress() + "> failed.");
+                LOGGER.warn("write send a request command to channel <" + channel.remoteAddress() + "> failed.");
                 throw new RemotingSendRequestException(RemotingHelper.parseChannelRemoteAddr(channel), e);
             }
         } else {
             if (timeoutMillis <= 0) {
                 throw new RemotingTooMuchRequestException("invokeOnewayImpl invoke too fast");
             } else {
-                plog.warn("invokeOnewayImpl tryAcquire semaphore timeout, " + timeoutMillis
+                LOGGER.warn("invokeOnewayImpl tryAcquire semaphore timeout, " + timeoutMillis
                         + " waiting thread nums: " + this.semaphoreOneway.getQueueLength());
-                plog.warn(request.toString());
+                LOGGER.warn(request.toString());
 
                 throw new RemotingTimeoutException("tryAcquire timeout(ms) " + timeoutMillis);
             }
         }
     }
 
-    class NettyEventExecutor extends ServiceThread {
-        private final LinkedBlockingQueue<NettyEvent> eventQueue = new LinkedBlockingQueue<NettyEvent>();
+    class RemotingEventExecutor extends ServiceThread {
+        private final LinkedBlockingQueue<RemotingEvent> eventQueue = new LinkedBlockingQueue<RemotingEvent>();
         private final int MaxSize = 10000;
 
-
-        public void putNettyEvent(final NettyEvent event) {
+        public void putRemotingEvent(final RemotingEvent event) {
             if (this.eventQueue.size() <= MaxSize) {
                 this.eventQueue.add(event);
             } else {
-                plog.warn("event queue size[{}] enough, so drop this event {}", this.eventQueue.size(),
+                LOGGER.warn("event queue size[{}] enough, so drop this event {}", this.eventQueue.size(),
                         event.toString());
             }
         }
 
-
         @Override
         public void run() {
-            plog.info(this.getServiceName() + " service started");
 
-            final ChannelEventListener listener = NettyRemotingAbstract.this.getChannelEventListener();
+
+            LOGGER.info(this.getServiceName() + " service started");
+
+            final ChannelEventListener listener = AbstractRemoting.this.getChannelEventListener();
 
             while (!this.isStoped()) {
                 try {
-                    NettyEvent event = this.eventQueue.poll(3000, TimeUnit.MILLISECONDS);
+                    RemotingEvent event = this.eventQueue.poll(3000, TimeUnit.MILLISECONDS);
                     if (event != null) {
                         switch (event.getType()) {
                             case ALL_IDLE:
@@ -404,23 +398,25 @@ public abstract class NettyRemotingAbstract {
                                 break;
                             default:
                                 break;
-
                         }
                     }
                 } catch (Exception e) {
-                    plog.warn(this.getServiceName() + " service has exception. ", e);
+                    LOGGER.warn(this.getServiceName() + " service has exception. ", e);
                 }
             }
 
-            plog.info(this.getServiceName() + " service end");
+            LOGGER.info(this.getServiceName() + " service end");
         }
 
-
         @Override
         public String getServiceName() {
-            return NettyEventExecutor.class.getSimpleName();
+            return RemotingEventExecutor.class.getSimpleName();
         }
     }
 
+    protected Codec getCodec(){
+        // TODO 改为SPI
+        return new DefaultCodec();
+    }
 
 }

+ 399 - 0
lts-core/src/main/java/com/lts/remoting/AbstractRemotingClient.java

@@ -0,0 +1,399 @@
+package com.lts.remoting;
+
+import com.lts.core.logger.Logger;
+import com.lts.core.logger.LoggerFactory;
+import com.lts.remoting.common.Pair;
+import com.lts.remoting.common.RemotingHelper;
+import com.lts.remoting.exception.*;
+import com.lts.remoting.protocol.RemotingCommand;
+
+import java.net.SocketAddress;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+
+/**
+ * Remoting客户端实现
+ */
+public abstract class AbstractRemotingClient extends AbstractRemoting implements RemotingClient {
+    protected static final Logger LOGGER = LoggerFactory.getLogger(RemotingHelper.RemotingLogName);
+
+    private static final long LockTimeoutMillis = 3000;
+
+    protected final RemotingClientConfig remotingClientConfig;
+
+    private final Lock lockChannelTables = new ReentrantLock();
+    private final ConcurrentHashMap<String /* addr */, ChannelWrapper> channelTables = new ConcurrentHashMap<String, ChannelWrapper>();
+    // 定时器
+    private final Timer timer = new Timer("ClientHouseKeepingService", true);
+    // 处理Callback应答器
+    private final ExecutorService publicExecutor;
+    protected final ChannelEventListener channelEventListener;
+
+    public AbstractRemotingClient(final RemotingClientConfig remotingClientConfig,
+                                  final ChannelEventListener channelEventListener) {
+        super(remotingClientConfig.getClientOnewaySemaphoreValue(), remotingClientConfig
+                .getClientAsyncSemaphoreValue());
+        this.remotingClientConfig = remotingClientConfig;
+        this.channelEventListener = channelEventListener;
+
+        int publicThreadNums = remotingClientConfig.getClientCallbackExecutorThreads();
+        if (publicThreadNums <= 0) {
+            publicThreadNums = 4;
+        }
+
+        this.publicExecutor = Executors.newFixedThreadPool(publicThreadNums, new ThreadFactory() {
+            private AtomicInteger threadIndex = new AtomicInteger(0);
+
+            @Override
+            public Thread newThread(Runnable r) {
+                return new Thread(r, "RemotingClientPublicExecutor_" + this.threadIndex.incrementAndGet());
+            }
+        });
+
+    }
+
+    @Override
+    public void start() throws RemotingException {
+
+        clientStart();
+
+        // 每隔1秒扫描下异步调用超时情况
+        this.timer.scheduleAtFixedRate(new TimerTask() {
+
+            @Override
+            public void run() {
+                try {
+                    AbstractRemotingClient.this.scanResponseTable();
+                } catch (Exception e) {
+                    LOGGER.error("scanResponseTable exception", e);
+                }
+            }
+        }, 1000 * 3, 1000);
+
+        if (this.channelEventListener != null) {
+            this.remotingEventExecutor.start();
+        }
+    }
+
+    protected abstract void clientStart() throws RemotingException;
+
+    @Override
+    public void shutdown() {
+        try {
+            this.timer.cancel();
+
+            for (ChannelWrapper cw : this.channelTables.values()) {
+                this.closeChannel(null, cw.getChannel());
+            }
+
+            this.channelTables.clear();
+
+            if (this.remotingEventExecutor != null) {
+                this.remotingEventExecutor.shutdown();
+            }
+
+            clientShutdown();
+
+        } catch (Exception e) {
+            LOGGER.error("NettyRemotingClient shutdown exception, ", e);
+        }
+
+        if (this.publicExecutor != null) {
+            try {
+                this.publicExecutor.shutdown();
+            } catch (Exception e) {
+                LOGGER.error("NettyRemotingServer shutdown exception, ", e);
+            }
+        }
+    }
+
+    protected abstract void clientShutdown();
+
+    private Channel getAndCreateChannel(final String addr) throws InterruptedException {
+
+        ChannelWrapper cw = this.channelTables.get(addr);
+        if (cw != null && cw.isConnected()) {
+            return cw.getChannel();
+        }
+
+        return this.createChannel(addr);
+    }
+
+    private Channel createChannel(final String addr) throws InterruptedException {
+        ChannelWrapper cw = this.channelTables.get(addr);
+        if (cw != null && cw.isConnected()) {
+            return cw.getChannel();
+        }
+
+        // 进入临界区后,不能有阻塞操作,网络连接采用异步方式
+        if (this.lockChannelTables.tryLock(LockTimeoutMillis, TimeUnit.MILLISECONDS)) {
+            try {
+                boolean createNewConnection = false;
+                cw = this.channelTables.get(addr);
+                if (cw != null) {
+                    // channel正常
+                    if (cw.isConnected()) {
+                        return cw.getChannel();
+                    }
+                    // 正在连接,退出锁等待
+                    else if (!cw.getChannelFuture().isDone()) {
+                        createNewConnection = false;
+                    }
+                    // 说明连接不成功
+                    else {
+                        this.channelTables.remove(addr);
+                        createNewConnection = true;
+                    }
+                }
+                // ChannelWrapper不存在
+                else {
+                    createNewConnection = true;
+                }
+
+                if (createNewConnection) {
+                    ChannelFuture channelFuture =
+                            connect(RemotingHelper.string2SocketAddress(addr));
+                    LOGGER.info("createChannel: begin to connect remote host[{}] asynchronously", addr);
+                    cw = new ChannelWrapper(channelFuture);
+                    this.channelTables.put(addr, cw);
+                }
+            } catch (Exception e) {
+                LOGGER.error("createChannel: create channel exception", e);
+            } finally {
+                this.lockChannelTables.unlock();
+            }
+        } else {
+            LOGGER.warn("createChannel: try to lock channel table, but timeout, {}ms", LockTimeoutMillis);
+        }
+
+        if (cw != null) {
+            ChannelFuture channelFuture = cw.getChannelFuture();
+
+            if (channelFuture.awaitUninterruptibly(this.remotingClientConfig.getConnectTimeoutMillis())) {
+                if (cw.isConnected()) {
+                    LOGGER.info("createChannel: connect remote host[{}] success, {}", addr,
+                            channelFuture.toString());
+                    return cw.getChannel();
+                } else {
+                    LOGGER.warn(
+                            "createChannel: connect remote host[" + addr + "] failed, "
+                                    + channelFuture.toString(), channelFuture.cause());
+                }
+            } else {
+                LOGGER.warn("createChannel: connect remote host[{}] timeout {}ms, {}", addr,
+                        this.remotingClientConfig.getConnectTimeoutMillis(), channelFuture.toString());
+            }
+        }
+
+        return null;
+    }
+
+    protected abstract ChannelFuture connect(SocketAddress socketAddress);
+
+    public void closeChannel(final String addr, final Channel channel) {
+        if (null == channel)
+            return;
+
+        final String addrRemote = null == addr ? RemotingHelper.parseChannelRemoteAddr(channel) : addr;
+
+        try {
+            if (this.lockChannelTables.tryLock(LockTimeoutMillis, TimeUnit.MILLISECONDS)) {
+                try {
+                    boolean removeItemFromTable = true;
+                    final ChannelWrapper prevCW = this.channelTables.get(addrRemote);
+
+                    LOGGER.info("closeChannel: begin close the channel[{}] Found: {}", addrRemote,
+                            (prevCW != null));
+
+                    if (null == prevCW) {
+                        LOGGER.info(
+                                "closeChannel: the channel[{}] has been removed from the channel table before",
+                                addrRemote);
+                        removeItemFromTable = false;
+                    } else if (prevCW.getChannel() != channel) {
+                        LOGGER.info(
+                                "closeChannel: the channel[{}] has been closed before, and has been created again, nothing to do.",
+                                addrRemote);
+                        removeItemFromTable = false;
+                    }
+
+                    if (removeItemFromTable) {
+                        this.channelTables.remove(addrRemote);
+                        LOGGER.info("closeChannel: the channel[{}] was removed from channel table", addrRemote);
+                    }
+
+                    RemotingHelper.closeChannel(channel);
+                } catch (Exception e) {
+                    LOGGER.error("closeChannel: close the channel exception", e);
+                } finally {
+                    this.lockChannelTables.unlock();
+                }
+            } else {
+                LOGGER.warn("closeChannel: try to lock channel table, but timeout, {}ms", LockTimeoutMillis);
+            }
+        } catch (InterruptedException e) {
+            LOGGER.error("closeChannel exception", e);
+        }
+    }
+
+    public void closeChannel(final Channel channel) {
+        if (null == channel)
+            return;
+
+        try {
+            if (this.lockChannelTables.tryLock(LockTimeoutMillis, TimeUnit.MILLISECONDS)) {
+                try {
+                    boolean removeItemFromTable = true;
+                    ChannelWrapper prevCW = null;
+                    String addrRemote = null;
+
+                    for (String key : channelTables.keySet()) {
+                        ChannelWrapper prev = this.channelTables.get(key);
+                        if (prev.getChannel() != null) {
+                            if (prev.getChannel() == channel) {
+                                prevCW = prev;
+                                addrRemote = key;
+                                break;
+                            }
+                        }
+                    }
+
+                    if (null == prevCW) {
+                        LOGGER.info(
+                                "eventCloseChannel: the channel[{}] has been removed from the channel table before", addrRemote);
+                        removeItemFromTable = false;
+                    }
+
+                    if (removeItemFromTable) {
+                        this.channelTables.remove(addrRemote);
+                        LOGGER.info("closeChannel: the channel[{}] was removed from channel table", addrRemote);
+                        RemotingHelper.closeChannel(channel);
+                    }
+                } catch (Exception e) {
+                    LOGGER.error("closeChannel: close the channel exception", e);
+                } finally {
+                    this.lockChannelTables.unlock();
+                }
+            } else {
+                LOGGER.warn("closeChannel: try to lock channel table, but timeout, {}ms", LockTimeoutMillis);
+            }
+        } catch (InterruptedException e) {
+            LOGGER.error("closeChannel exception", e);
+        }
+    }
+
+    @Override
+    public void registerProcessor(int requestCode, RemotingProcessor processor, ExecutorService executor) {
+        ExecutorService executorThis = executor;
+        if (null == executor) {
+            executorThis = this.publicExecutor;
+        }
+
+        Pair<RemotingProcessor, ExecutorService> pair =
+                new Pair<RemotingProcessor, ExecutorService>(processor, executorThis);
+        this.processorTable.put(requestCode, pair);
+    }
+
+    @Override
+    public void registerDefaultProcessor(RemotingProcessor processor, ExecutorService executor) {
+        this.defaultRequestProcessor = new Pair<RemotingProcessor, ExecutorService>(processor, executor);
+    }
+
+    @Override
+    public RemotingCommand invokeSync(String addr, final RemotingCommand request, long timeoutMillis)
+            throws InterruptedException, RemotingConnectException, RemotingSendRequestException,
+            RemotingTimeoutException {
+        final Channel channel = this.getAndCreateChannel(addr);
+        if (channel != null && channel.isConnected()) {
+            try {
+                return this.invokeSyncImpl(channel, request, timeoutMillis);
+            } catch (RemotingSendRequestException e) {
+                LOGGER.warn("invokeSync: send request exception, so close the channel[{}]", addr);
+                this.closeChannel(addr, channel);
+                throw e;
+            } catch (RemotingTimeoutException e) {
+                LOGGER.warn("invokeSync: wait response timeout exception, the channel[{}]", addr);
+                // 超时异常如果关闭连接可能会产生连锁反应
+                // this.closeChannel(addr, channel);
+                throw e;
+            }
+        } else {
+            this.closeChannel(addr, channel);
+            throw new RemotingConnectException(addr);
+        }
+    }
+
+    @Override
+    public void invokeAsync(String addr, RemotingCommand request, long timeoutMillis,
+                            AsyncCallback asyncCallback) throws InterruptedException, RemotingConnectException,
+            RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException {
+        final Channel channel = this.getAndCreateChannel(addr);
+        if (channel != null && channel.isConnected()) {
+            try {
+                this.invokeAsyncImpl(channel, request, timeoutMillis, asyncCallback);
+            } catch (RemotingSendRequestException e) {
+                LOGGER.warn("invokeAsync: send request exception, so close the channel[{}]", addr);
+                this.closeChannel(addr, channel);
+                throw e;
+            }
+        } else {
+            this.closeChannel(addr, channel);
+            throw new RemotingConnectException(addr);
+        }
+    }
+
+    @Override
+    public void invokeOneway(String addr, RemotingCommand request, long timeoutMillis)
+            throws InterruptedException, RemotingConnectException, RemotingTooMuchRequestException,
+            RemotingTimeoutException, RemotingSendRequestException {
+        final Channel channel = this.getAndCreateChannel(addr);
+        if (channel != null && channel.isConnected()) {
+            try {
+                this.invokeOnewayImpl(channel, request, timeoutMillis);
+            } catch (RemotingSendRequestException e) {
+                LOGGER.warn("invokeOneway: send request exception, so close the channel[{}]", addr);
+                this.closeChannel(addr, channel);
+                throw e;
+            }
+        } else {
+            this.closeChannel(addr, channel);
+            throw new RemotingConnectException(addr);
+        }
+    }
+
+    @Override
+    protected ExecutorService getCallbackExecutor() {
+        return this.publicExecutor;
+    }
+
+    @Override
+    public ChannelEventListener getChannelEventListener() {
+        return channelEventListener;
+    }
+
+    private class ChannelWrapper {
+        private final ChannelFuture channelFuture;
+
+        public ChannelWrapper(ChannelFuture channelFuture) {
+            this.channelFuture = channelFuture;
+        }
+
+        public boolean isConnected() {
+            return channelFuture.isConnected();
+        }
+
+        private Channel getChannel() {
+            return channelFuture.getChannel();
+        }
+
+        private ChannelFuture getChannelFuture() {
+            return this.channelFuture;
+        }
+    }
+
+}

+ 157 - 0
lts-core/src/main/java/com/lts/remoting/AbstractRemotingServer.java

@@ -0,0 +1,157 @@
+package com.lts.remoting;
+
+import com.lts.core.logger.Logger;
+import com.lts.core.logger.LoggerFactory;
+import com.lts.remoting.common.Pair;
+import com.lts.remoting.common.RemotingHelper;
+import com.lts.remoting.exception.RemotingException;
+import com.lts.remoting.exception.RemotingSendRequestException;
+import com.lts.remoting.exception.RemotingTimeoutException;
+import com.lts.remoting.exception.RemotingTooMuchRequestException;
+import com.lts.remoting.protocol.RemotingCommand;
+
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+
+/**
+ * Remoting服务端实现
+ */
+public abstract class AbstractRemotingServer extends AbstractRemoting implements RemotingServer {
+    protected static final Logger LOGGER = LoggerFactory.getLogger(RemotingHelper.RemotingLogName);
+
+    protected final RemotingServerConfig remotingServerConfig;
+    // 处理Callback应答器
+    private final ExecutorService publicExecutor;
+    protected final ChannelEventListener channelEventListener;
+    // 定时器
+    private final Timer timer = new Timer("ServerHouseKeepingService", true);
+
+    public AbstractRemotingServer(final RemotingServerConfig remotingServerConfig,
+                                  final ChannelEventListener channelEventListener) {
+        super(remotingServerConfig.getServerOnewaySemaphoreValue(),
+                remotingServerConfig.getServerAsyncSemaphoreValue());
+        this.remotingServerConfig = remotingServerConfig;
+        this.channelEventListener = channelEventListener;
+
+        int publicThreadNums = remotingServerConfig.getServerCallbackExecutorThreads();
+        if (publicThreadNums <= 0) {
+            publicThreadNums = 4;
+        }
+
+        this.publicExecutor = Executors.newFixedThreadPool(publicThreadNums, new ThreadFactory() {
+            private AtomicInteger threadIndex = new AtomicInteger(0);
+
+            @Override
+            public Thread newThread(Runnable r) {
+                return new Thread(r, "RemotingServerPublicExecutor_" + this.threadIndex.incrementAndGet());
+            }
+        });
+    }
+
+    @Override
+    public final void start() throws RemotingException {
+
+        serverStart();
+
+        if (channelEventListener != null) {
+            this.remotingEventExecutor.start();
+        }
+
+        // 每隔1秒扫描下异步调用超时情况
+        this.timer.scheduleAtFixedRate(new TimerTask() {
+
+            @Override
+            public void run() {
+                try {
+                    AbstractRemotingServer.this.scanResponseTable();
+                } catch (Exception e) {
+                    LOGGER.error("scanResponseTable exception", e);
+                }
+            }
+        }, 1000 * 3, 1000);
+    }
+
+    protected abstract void serverStart() throws RemotingException;
+
+    @Override
+    public void registerProcessor(int requestCode, RemotingProcessor processor, ExecutorService executor) {
+        ExecutorService executorThis = executor;
+        if (null == executor) {
+            executorThis = this.publicExecutor;
+        }
+
+        Pair<RemotingProcessor, ExecutorService> pair =
+                new Pair<RemotingProcessor, ExecutorService>(processor, executorThis);
+        this.processorTable.put(requestCode, pair);
+    }
+
+    @Override
+    public void registerDefaultProcessor(RemotingProcessor processor, ExecutorService executor) {
+        this.defaultRequestProcessor = new Pair<RemotingProcessor, ExecutorService>(processor, executor);
+    }
+
+    @Override
+    public RemotingCommand invokeSync(final Channel channel, final RemotingCommand request,
+                                      final long timeoutMillis) throws InterruptedException, RemotingSendRequestException,
+            RemotingTimeoutException {
+        return this.invokeSyncImpl(channel, request, timeoutMillis);
+    }
+
+    @Override
+    public void invokeAsync(Channel channel, RemotingCommand request, long timeoutMillis,
+                            AsyncCallback asyncCallback) throws InterruptedException, RemotingTooMuchRequestException,
+            RemotingTimeoutException, RemotingSendRequestException {
+        this.invokeAsyncImpl(channel, request, timeoutMillis, asyncCallback);
+    }
+
+    @Override
+    public void invokeOneway(Channel channel, RemotingCommand request, long timeoutMillis)
+            throws InterruptedException, RemotingTooMuchRequestException, RemotingTimeoutException,
+            RemotingSendRequestException {
+        this.invokeOnewayImpl(channel, request, timeoutMillis);
+    }
+
+    @Override
+    public void shutdown() {
+        try {
+            if (this.timer != null) {
+                this.timer.cancel();
+            }
+
+            if (this.remotingEventExecutor != null) {
+                this.remotingEventExecutor.shutdown();
+            }
+
+            serverShutdown();
+
+        } catch (Exception e) {
+            LOGGER.error("RemotingServer shutdown exception, ", e);
+        }
+
+        if (this.publicExecutor != null) {
+            try {
+                this.publicExecutor.shutdown();
+            } catch (Exception e) {
+                LOGGER.error("RemotingServer shutdown exception, ", e);
+            }
+        }
+    }
+
+    protected abstract void serverShutdown();
+
+    @Override
+    public ChannelEventListener getChannelEventListener() {
+        return channelEventListener;
+    }
+
+
+    @Override
+    protected ExecutorService getCallbackExecutor() {
+        return this.publicExecutor;
+    }
+}

+ 2 - 3
lts-core/src/main/java/com/lts/remoting/InvokeCallback.java → lts-core/src/main/java/com/lts/remoting/AsyncCallback.java

@@ -1,11 +1,10 @@
 package com.lts.remoting;
 
-import com.lts.remoting.netty.ResponseFuture;
-
 
 /**
  * 异步调用应答回调接口
  */
-public interface InvokeCallback {
+public interface AsyncCallback {
+
     public void operationComplete(final ResponseFuture responseFuture);
 }

+ 24 - 0
lts-core/src/main/java/com/lts/remoting/Channel.java

@@ -0,0 +1,24 @@
+package com.lts.remoting;
+
+
+import java.net.SocketAddress;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/3/15.
+ */
+public interface Channel {
+
+    SocketAddress localAddress();
+
+    SocketAddress remoteAddress();
+
+    ChannelHandler writeAndFlush(Object msg);
+
+    ChannelHandler close();
+
+    boolean isConnected();
+
+    boolean isOpen();
+
+    boolean isClosed();
+}

+ 0 - 7
lts-core/src/main/java/com/lts/remoting/ChannelEventListener.java

@@ -1,9 +1,5 @@
 package com.lts.remoting;
 
-import io.netty.channel.Channel;
-import io.netty.handler.timeout.IdleState;
-
-
 /**
  * 监听Channel的事件,包括连接断开、连接建立、连接异常,传送这些事件到应用层
  */
@@ -11,13 +7,10 @@ public interface ChannelEventListener {
 
     public void onChannelConnect(final String remoteAddr, final Channel channel);
 
-
     public void onChannelClose(final String remoteAddr, final Channel channel);
 
-
     public void onChannelException(final String remoteAddr, final Channel channel);
 
-
     public void onChannelIdle(IdleState idleState, final String remoteAddr, final Channel channel);
 
 }

+ 17 - 0
lts-core/src/main/java/com/lts/remoting/ChannelFuture.java

@@ -0,0 +1,17 @@
+package com.lts.remoting;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/4/15.
+ */
+public interface ChannelFuture {
+
+    boolean isConnected();
+
+    Channel getChannel();
+
+    boolean awaitUninterruptibly(long timeoutMillis);
+
+    boolean isDone();
+
+    Throwable cause();
+}

+ 10 - 0
lts-core/src/main/java/com/lts/remoting/ChannelHandler.java

@@ -0,0 +1,10 @@
+package com.lts.remoting;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/3/15.
+ */
+public interface ChannelHandler {
+
+    ChannelHandler addListener(ChannelHandlerListener listener);
+
+}

+ 11 - 0
lts-core/src/main/java/com/lts/remoting/ChannelHandlerListener.java

@@ -0,0 +1,11 @@
+package com.lts.remoting;
+
+import java.util.EventListener;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/3/15.
+ */
+public interface ChannelHandlerListener extends EventListener {
+
+    void operationComplete(Future future) throws Exception;
+}

+ 12 - 0
lts-core/src/main/java/com/lts/remoting/Future.java

@@ -0,0 +1,12 @@
+package com.lts.remoting;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/3/15.
+ */
+public interface Future {
+
+    boolean isSuccess();
+
+    Throwable cause();
+
+}

+ 19 - 0
lts-core/src/main/java/com/lts/remoting/IdleState.java

@@ -0,0 +1,19 @@
+package com.lts.remoting;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/3/15.
+ */
+public enum IdleState {
+    /**
+     * No data was received for a while.
+     */
+    READER_IDLE,
+    /**
+     * No data was sent for a while.
+     */
+    WRITER_IDLE,
+    /**
+     * No data was either received or sent for a while.
+     */
+    ALL_IDLE
+}

+ 5 - 9
lts-core/src/main/java/com/lts/remoting/RemotingClient.java

@@ -1,10 +1,6 @@
 package com.lts.remoting;
 
-import com.lts.remoting.exception.RemotingConnectException;
-import com.lts.remoting.exception.RemotingSendRequestException;
-import com.lts.remoting.exception.RemotingTimeoutException;
-import com.lts.remoting.exception.RemotingTooMuchRequestException;
-import com.lts.remoting.netty.NettyRequestProcessor;
+import com.lts.remoting.exception.*;
 import com.lts.remoting.protocol.RemotingCommand;
 
 import java.util.concurrent.ExecutorService;
@@ -15,7 +11,7 @@ import java.util.concurrent.ExecutorService;
  */
 public interface RemotingClient {
 
-    public void start();
+    public void start() throws RemotingException;
 
     /**
      * 同步调用
@@ -28,7 +24,7 @@ public interface RemotingClient {
      * 异步调用
      */
     public void invokeAsync(final String addr, final RemotingCommand request, final long timeoutMillis,
-                            final InvokeCallback invokeCallback) throws InterruptedException, RemotingConnectException,
+                            final AsyncCallback asyncCallback) throws InterruptedException, RemotingConnectException,
             RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException;
 
     /**
@@ -41,13 +37,13 @@ public interface RemotingClient {
     /**
      * 注册处理器
      */
-    public void registerProcessor(final int requestCode, final NettyRequestProcessor processor,
+    public void registerProcessor(final int requestCode, final RemotingProcessor processor,
                                   final ExecutorService executor);
 
     /**
      * 注册默认处理器
      */
-    public void registerDefaultProcessor(final NettyRequestProcessor processor, final ExecutorService executor);
+    public void registerDefaultProcessor(final RemotingProcessor processor, final ExecutorService executor);
 
     public void shutdown();
 }

+ 3 - 3
lts-core/src/main/java/com/lts/remoting/netty/NettyClientConfig.java → lts-core/src/main/java/com/lts/remoting/RemotingClientConfig.java

@@ -1,11 +1,11 @@
-package com.lts.remoting.netty;
+package com.lts.remoting;
 
 import com.lts.core.constant.Constants;
 
 /**
- * Netty客户端配置类
+ * 客户端配置类
  */
-public class NettyClientConfig {
+public class RemotingClientConfig {
     // 处理Server Response/Request
     private int clientWorkerThreads = 4;
     private int clientCallbackExecutorThreads = Constants.AVAILABLE_PROCESSOR * 2;

+ 7 - 14
lts-core/src/main/java/com/lts/remoting/netty/NettyEvent.java → lts-core/src/main/java/com/lts/remoting/RemotingEvent.java

@@ -1,39 +1,32 @@
-package com.lts.remoting.netty;
-
-import io.netty.channel.Channel;
-
+package com.lts.remoting;
 
 /**
- * Netty产生的各种事件
+ * 事件
  */
-public class NettyEvent {
-    private final NettyEventType type;
+public class RemotingEvent {
+
+    private final RemotingEventType type;
     private final String remoteAddr;
     private final Channel channel;
 
-
-    public NettyEvent(NettyEventType type, String remoteAddr, Channel channel) {
+    public RemotingEvent(RemotingEventType type, String remoteAddr, Channel channel) {
         this.type = type;
         this.remoteAddr = remoteAddr;
         this.channel = channel;
     }
 
-
-    public NettyEventType getType() {
+    public RemotingEventType getType() {
         return type;
     }
 
-
     public String getRemoteAddr() {
         return remoteAddr;
     }
 
-
     public Channel getChannel() {
         return channel;
     }
 
-
     @Override
     public String toString() {
         return "NettyEvent [type=" + type + ", remoteAddr=" + remoteAddr + ", channel=" + channel + "]";

+ 3 - 3
lts-core/src/main/java/com/lts/remoting/netty/NettyEventType.java → lts-core/src/main/java/com/lts/remoting/RemotingEventType.java

@@ -1,9 +1,9 @@
-package com.lts.remoting.netty;
+package com.lts.remoting;
 
 /**
- * Netty产生的事件类型
+ * 事件类型
  */
-public enum NettyEventType {
+public enum RemotingEventType {
     CONNECT,
     CLOSE,
     READER_IDLE,

+ 3 - 5
lts-core/src/main/java/com/lts/remoting/netty/NettyRequestProcessor.java → lts-core/src/main/java/com/lts/remoting/RemotingProcessor.java

@@ -1,14 +1,12 @@
-package com.lts.remoting.netty;
+package com.lts.remoting;
 
 import com.lts.remoting.exception.RemotingCommandException;
 import com.lts.remoting.protocol.RemotingCommand;
-import io.netty.channel.ChannelHandlerContext;
-
 
 /**
  * 接收请求处理器,服务器与客户端通用
  */
-public interface NettyRequestProcessor {
-    public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request)
+public interface RemotingProcessor {
+    public RemotingCommand processRequest(Channel channel, RemotingCommand request)
             throws RemotingCommandException;
 }

+ 5 - 6
lts-core/src/main/java/com/lts/remoting/RemotingServer.java

@@ -1,11 +1,10 @@
 package com.lts.remoting;
 
+import com.lts.remoting.exception.RemotingException;
 import com.lts.remoting.exception.RemotingSendRequestException;
 import com.lts.remoting.exception.RemotingTimeoutException;
 import com.lts.remoting.exception.RemotingTooMuchRequestException;
-import com.lts.remoting.netty.NettyRequestProcessor;
 import com.lts.remoting.protocol.RemotingCommand;
-import io.netty.channel.Channel;
 
 import java.util.concurrent.ExecutorService;
 
@@ -15,19 +14,19 @@ import java.util.concurrent.ExecutorService;
  */
 public interface RemotingServer {
 
-    public void start() throws InterruptedException;
+    public void start() throws RemotingException;
 
 
     /**
      * 注册请求处理器,ExecutorService必须要对应一个队列大小有限制的阻塞队列,防止OOM
      */
-    public void registerProcessor(final int requestCode, final NettyRequestProcessor processor,
+    public void registerProcessor(final int requestCode, final RemotingProcessor processor,
                                   final ExecutorService executor);
 
     /**
      * 注册默认请求处理器
      */
-    public void registerDefaultProcessor(final NettyRequestProcessor processor, final ExecutorService executor);
+    public void registerDefaultProcessor(final RemotingProcessor processor, final ExecutorService executor);
 
 
     /**
@@ -41,7 +40,7 @@ public interface RemotingServer {
      * 异步调用
      */
     public void invokeAsync(final Channel channel, final RemotingCommand request, final long timeoutMillis,
-                            final InvokeCallback invokeCallback) throws InterruptedException,
+                            final AsyncCallback asyncCallback) throws InterruptedException,
             RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException;
 
     /**

+ 3 - 17
lts-core/src/main/java/com/lts/remoting/netty/NettyServerConfig.java → lts-core/src/main/java/com/lts/remoting/RemotingServerConfig.java

@@ -1,11 +1,11 @@
-package com.lts.remoting.netty;
+package com.lts.remoting;
 
 import com.lts.core.constant.Constants;
 
 /**
- * Netty服务端配置
+ * 服务端配置
  */
-public class NettyServerConfig {
+public class RemotingServerConfig {
     private int listenPort = 8888;
     private int serverWorkerThreads = 32;
     private int serverCallbackExecutorThreads = Constants.AVAILABLE_PROCESSOR * 2;
@@ -17,72 +17,58 @@ public class NettyServerConfig {
     private int writerIdleTimeSeconds = 0;
     private int serverChannelMaxIdleTimeSeconds = 120;
 
-
     public int getListenPort() {
         return listenPort;
     }
 
-
     public void setListenPort(int listenPort) {
         this.listenPort = listenPort;
     }
 
-
     public int getServerWorkerThreads() {
         return serverWorkerThreads;
     }
 
-
     public void setServerWorkerThreads(int serverWorkerThreads) {
         this.serverWorkerThreads = serverWorkerThreads;
     }
 
-
     public int getServerSelectorThreads() {
         return serverSelectorThreads;
     }
 
-
     public void setServerSelectorThreads(int serverSelectorThreads) {
         this.serverSelectorThreads = serverSelectorThreads;
     }
 
-
     public int getServerOnewaySemaphoreValue() {
         return serverOnewaySemaphoreValue;
     }
 
-
     public void setServerOnewaySemaphoreValue(int serverOnewaySemaphoreValue) {
         this.serverOnewaySemaphoreValue = serverOnewaySemaphoreValue;
     }
 
-
     public int getServerCallbackExecutorThreads() {
         return serverCallbackExecutorThreads;
     }
 
-
     public void setServerCallbackExecutorThreads(int serverCallbackExecutorThreads) {
         this.serverCallbackExecutorThreads = serverCallbackExecutorThreads;
     }
 
-
     public int getServerAsyncSemaphoreValue() {
         return serverAsyncSemaphoreValue;
     }
 
-
     public void setServerAsyncSemaphoreValue(int serverAsyncSemaphoreValue) {
         this.serverAsyncSemaphoreValue = serverAsyncSemaphoreValue;
     }
 
-
     public int getServerChannelMaxIdleTimeSeconds() {
         return serverChannelMaxIdleTimeSeconds;
     }
 
-
     public void setServerChannelMaxIdleTimeSeconds(int serverChannelMaxIdleTimeSeconds) {
         this.serverChannelMaxIdleTimeSeconds = serverChannelMaxIdleTimeSeconds;
     }

+ 9 - 27
lts-core/src/main/java/com/lts/remoting/netty/ResponseFuture.java → lts-core/src/main/java/com/lts/remoting/ResponseFuture.java

@@ -1,7 +1,6 @@
-package com.lts.remoting.netty;
+package com.lts.remoting;
 
 import com.lts.core.support.SystemClock;
-import com.lts.remoting.InvokeCallback;
 import com.lts.remoting.common.SemaphoreReleaseOnlyOnce;
 import com.lts.remoting.protocol.RemotingCommand;
 
@@ -16,7 +15,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 public class ResponseFuture {
     private final int opaque;
     private final long timeoutMillis;
-    private final InvokeCallback invokeCallback;
+    private final AsyncCallback asyncCallback;
     private final long beginTimestamp = SystemClock.now();
     private final CountDownLatch countDownLatch = new CountDownLatch(1);
     // 保证信号量至多至少只被释放一次
@@ -27,105 +26,88 @@ public class ResponseFuture {
     private volatile boolean sendRequestOK = true;
     private volatile Throwable cause;
 
-
-    public ResponseFuture(int opaque, long timeoutMillis, InvokeCallback invokeCallback,
+    public ResponseFuture(int opaque, long timeoutMillis, AsyncCallback asyncCallback,
                           SemaphoreReleaseOnlyOnce once) {
         this.opaque = opaque;
         this.timeoutMillis = timeoutMillis;
-        this.invokeCallback = invokeCallback;
+        this.asyncCallback = asyncCallback;
         this.once = once;
     }
 
-
     public void executeInvokeCallback() {
-        if (invokeCallback != null) {
+        if (asyncCallback != null) {
             if (this.executeCallbackOnlyOnce.compareAndSet(false, true)) {
-                invokeCallback.operationComplete(this);
+                asyncCallback.operationComplete(this);
             }
         }
     }
 
-
     public void release() {
         if (this.once != null) {
             this.once.release();
         }
     }
 
-
     public boolean isTimeout() {
         long diff = SystemClock.now() - this.beginTimestamp;
         return diff > this.timeoutMillis;
     }
 
-
     public RemotingCommand waitResponse(final long timeoutMillis) throws InterruptedException {
         this.countDownLatch.await(timeoutMillis, TimeUnit.MILLISECONDS);
         return this.responseCommand;
     }
 
-
     public void putResponse(final RemotingCommand responseCommand) {
         this.responseCommand = responseCommand;
         this.countDownLatch.countDown();
     }
 
-
     public long getBeginTimestamp() {
         return beginTimestamp;
     }
 
-
     public boolean isSendRequestOK() {
         return sendRequestOK;
     }
 
-
     public void setSendRequestOK(boolean sendRequestOK) {
         this.sendRequestOK = sendRequestOK;
     }
 
-
     public long getTimeoutMillis() {
         return timeoutMillis;
     }
 
-
-    public InvokeCallback getInvokeCallback() {
-        return invokeCallback;
+    public AsyncCallback getAsyncCallback() {
+        return asyncCallback;
     }
 
-
     public Throwable getCause() {
         return cause;
     }
 
-
     public void setCause(Throwable cause) {
         this.cause = cause;
     }
 
-
     public RemotingCommand getResponseCommand() {
         return responseCommand;
     }
 
-
     public void setResponseCommand(RemotingCommand responseCommand) {
         this.responseCommand = responseCommand;
     }
 
-
     public int getOpaque() {
         return opaque;
     }
 
-
     @Override
     public String toString() {
         return "ResponseFuture [responseCommand=" + responseCommand + ", sendRequestOK=" + sendRequestOK
                 + ", cause=" + cause + ", opaque=" + opaque + ", timeoutMillis=" + timeoutMillis
-                + ", invokeCallback=" + invokeCallback + ", beginTimestamp=" + beginTimestamp
+                + ", invokeCallback=" + asyncCallback + ", beginTimestamp=" + beginTimestamp
                 + ", countDownLatch=" + countDownLatch + "]";
     }
 }

+ 16 - 0
lts-core/src/main/java/com/lts/remoting/codec/Codec.java

@@ -0,0 +1,16 @@
+package com.lts.remoting.codec;
+
+import com.lts.remoting.protocol.RemotingCommand;
+
+import java.nio.ByteBuffer;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/5/15.
+ */
+public interface Codec {
+
+    RemotingCommand decode(final ByteBuffer byteBuffer) throws Exception;
+
+    ByteBuffer encode(final RemotingCommand remotingCommand) throws Exception;
+
+}

+ 105 - 0
lts-core/src/main/java/com/lts/remoting/codec/DefaultCodec.java

@@ -0,0 +1,105 @@
+package com.lts.remoting.codec;
+
+import com.lts.remoting.CommandBody;
+import com.lts.remoting.protocol.RemotingCommand;
+import com.lts.remoting.protocol.RemotingSerializable;
+
+import java.nio.ByteBuffer;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/5/15.
+ * <p/>
+ * // Remoting通信协议
+ * //
+ * // 协议格式 <length> <header length> <header data> <body length> <body data> <body class>
+ * //            1        2               3             4             5             6
+ * // 协议分4部分,含义分别如下
+ * //     1、大端4个字节整数,等于2、3、4、5、6长度总和
+ * //     2、header 信息长度 大端4个字节整数,等于3的长度
+ * //     3、header 信息内容
+ * //     4、body 信息长度  大端4个字节整数,等于5的长度
+ * //     5、body 信息内容
+ * //     6、body 的class名称
+ * </p>
+ */
+public class DefaultCodec implements Codec {
+
+    @Override
+    public RemotingCommand decode(ByteBuffer byteBuffer) throws Exception {
+
+        int length = byteBuffer.limit();
+        int headerLength = byteBuffer.getInt();
+        byte[] headerData = new byte[headerLength];
+        byteBuffer.get(headerData);
+
+        RemotingCommand cmd = RemotingSerializable.decode(headerData, RemotingCommand.class);
+
+        if (length - 4 - headerLength > 0) {
+            int bodyLength = byteBuffer.getInt();
+            int bodyClassLength = length - 4 - headerLength - 4 - bodyLength;
+
+            if (bodyLength > 0) {
+
+                byte[] bodyData = new byte[bodyLength];
+                byteBuffer.get(bodyData);
+
+                byte[] bodyClassData = new byte[bodyClassLength];
+                byteBuffer.get(bodyClassData);
+
+                cmd.setBody((CommandBody) RemotingSerializable.decode(bodyData, Class.forName(new String(bodyClassData))));
+            }
+        }
+        return cmd;
+    }
+
+    @Override
+    public ByteBuffer encode(RemotingCommand remotingCommand) {
+
+        // 1> header length size
+        int length = 4;
+
+        // 2> header data length
+        byte[] headerData = RemotingSerializable.encode(remotingCommand);
+        length += headerData.length;
+
+        byte[] bodyData = null;
+        byte[] bodyClass = null;
+
+        CommandBody body = remotingCommand.getBody();
+
+        if (body != null) {
+            // body data
+            bodyData = RemotingSerializable.encode(body);
+            length += bodyData.length;
+
+            bodyClass = body.getClass().getName().getBytes();
+            length += bodyClass.length;
+
+            length += 4;
+        }
+
+        ByteBuffer result = ByteBuffer.allocate(4 + length);
+
+        // length
+        result.putInt(length);
+
+        // header length
+        result.putInt(headerData.length);
+
+        // header data
+        result.put(headerData);
+
+        if (bodyData != null) {
+            //  body length
+            result.putInt(bodyData.length);
+            //  body data
+            result.put(bodyData);
+            // body class
+            result.put(bodyClass);
+        }
+
+        result.flip();
+
+        return result;
+    }
+}

+ 0 - 5
lts-core/src/main/java/com/lts/remoting/common/Pair.java

@@ -7,28 +7,23 @@ public class Pair<T1, T2> {
     private T1 object1;
     private T2 object2;
 
-
     public Pair(T1 object1, T2 object2) {
         this.object1 = object1;
         this.object2 = object2;
     }
 
-
     public T1 getObject1() {
         return object1;
     }
 
-
     public void setObject1(T1 object1) {
         this.object1 = object1;
     }
 
-
     public T2 getObject2() {
         return object2;
     }
 
-
     public void setObject2(T2 object2) {
         this.object2 = object2;
     }

+ 19 - 3
lts-core/src/main/java/com/lts/remoting/common/RemotingHelper.java

@@ -1,6 +1,10 @@
 package com.lts.remoting.common;
 
-import io.netty.channel.Channel;
+import com.lts.core.logger.Logger;
+import com.lts.core.logger.LoggerFactory;
+import com.lts.remoting.Channel;
+import com.lts.remoting.ChannelHandlerListener;
+import com.lts.remoting.Future;
 
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
@@ -11,7 +15,9 @@ import java.net.SocketAddress;
  */
 public class RemotingHelper {
 
-    public static final String RemotingLogName = "LTS.Remoting";
+    private static final Logger LOGGER = LoggerFactory.getLogger(RemotingHelper.RemotingLogName);
+
+    public static final String RemotingLogName = "LtsRemoting";
 
     public static String exceptionSimpleDesc(final Exception e) {
         StringBuilder sb = new StringBuilder();
@@ -37,7 +43,6 @@ public class RemotingHelper {
         return new InetSocketAddress(s[0], Integer.valueOf(s[1]));
     }
 
-
     public static String parseChannelRemoteAddr(final Channel channel) {
         if (null == channel) {
             return "";
@@ -57,4 +62,15 @@ public class RemotingHelper {
         return "";
     }
 
+    public static void closeChannel(Channel channel) {
+        final String addrRemote = RemotingHelper.parseChannelRemoteAddr(channel);
+        channel.close().addListener(new ChannelHandlerListener() {
+            @Override
+            public void operationComplete(Future future) throws Exception {
+                LOGGER.info("closeChannel: close the connection to remote address[{}] result: {}", addrRemote,
+                        future.isSuccess());
+            }
+        });
+    }
+
 }

+ 0 - 193
lts-core/src/main/java/com/lts/remoting/common/RemotingUtil.java

@@ -1,193 +0,0 @@
-package com.lts.remoting.common;
-
-import com.lts.core.logger.Logger;
-import com.lts.core.logger.LoggerFactory;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelFutureListener;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.net.*;
-import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
-import java.nio.channels.spi.SelectorProvider;
-import java.util.ArrayList;
-import java.util.Enumeration;
-
-
-/**
- * 网络相关方法
- */
-public class RemotingUtil {
-
-    public static final String OS_NAME = System.getProperty("os.name");
-    private static final Logger logger = LoggerFactory.getLogger(RemotingHelper.RemotingLogName);
-    private static boolean isLinuxPlatform = false;
-
-    static {
-        if (OS_NAME != null && OS_NAME.toLowerCase().indexOf("linux") >= 0) {
-            isLinuxPlatform = true;
-        }
-    }
-
-
-    public static boolean isLinuxPlatform() {
-        return isLinuxPlatform;
-    }
-
-
-    public static Selector openSelector() throws IOException {
-        Selector result = null;
-        // 在linux平台,尽量启用epoll实现
-        if (isLinuxPlatform()) {
-            try {
-                final Class<?> providerClazz = Class.forName("sun.nio.ch.EPollSelectorProvider");
-                if (providerClazz != null) {
-                    try {
-                        final Method method = providerClazz.getMethod("provider");
-                        if (method != null) {
-                            final SelectorProvider selectorProvider = (SelectorProvider) method.invoke(null);
-                            if (selectorProvider != null) {
-                                result = selectorProvider.openSelector();
-                            }
-                        }
-                    } catch (final Exception e) {
-                        // ignore
-                    }
-                }
-            } catch (final Exception e) {
-                // ignore
-            }
-        }
-
-        if (result == null) {
-            result = Selector.open();
-        }
-
-        return result;
-    }
-
-
-    public static String getLocalAddress() {
-        try {
-            // 遍历网卡,查找一个非回路ip地址并返回
-            Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces();
-            ArrayList<String> ipv4Result = new ArrayList<String>();
-            ArrayList<String> ipv6Result = new ArrayList<String>();
-            while (enumeration.hasMoreElements()) {
-                final NetworkInterface networkInterface = enumeration.nextElement();
-                final Enumeration<InetAddress> en = networkInterface.getInetAddresses();
-                while (en.hasMoreElements()) {
-                    final InetAddress address = en.nextElement();
-                    if (!address.isLoopbackAddress()) {
-                        if (address instanceof Inet6Address) {
-                            ipv6Result.add(normalizeHostAddress(address));
-                        } else {
-                            ipv4Result.add(normalizeHostAddress(address));
-                        }
-                    }
-                }
-            }
-
-            // 优先使用ipv4
-            if (!ipv4Result.isEmpty()) {
-                for (String ip : ipv4Result) {
-                    if (ip.startsWith("127.0") || ip.startsWith("192.168")) {
-                        continue;
-                    }
-
-                    return ip;
-                }
-
-                // 取最后一个
-                return ipv4Result.get(ipv4Result.size() - 1);
-            }
-            // 然后使用ipv6
-            else if (!ipv6Result.isEmpty()) {
-                return ipv6Result.get(0);
-            }
-            // 然后使用本地ip
-            final InetAddress localHost = InetAddress.getLocalHost();
-            return normalizeHostAddress(localHost);
-        } catch (SocketException e) {
-            logger.error(e.getMessage(), e);
-        } catch (UnknownHostException e) {
-            logger.error(e.getMessage(), e);
-        }
-
-        return null;
-    }
-
-
-    public static String normalizeHostAddress(final InetAddress localHost) {
-        if (localHost instanceof Inet6Address) {
-            return "[" + localHost.getHostAddress() + "]";
-        } else {
-            return localHost.getHostAddress();
-        }
-    }
-
-
-    /**
-     * IP:PORT
-     */
-    public static SocketAddress string2SocketAddress(final String addr) {
-        String[] s = addr.split(":");
-        InetSocketAddress isa = new InetSocketAddress(s[0], Integer.valueOf(s[1]));
-        return isa;
-    }
-
-
-    public static String socketAddress2String(final SocketAddress addr) {
-        StringBuilder sb = new StringBuilder();
-        InetSocketAddress inetSocketAddress = (InetSocketAddress) addr;
-        sb.append(inetSocketAddress.getAddress().getHostAddress());
-        sb.append(":");
-        sb.append(inetSocketAddress.getPort());
-        return sb.toString();
-    }
-
-
-    public static SocketChannel connect(SocketAddress remote) {
-        return connect(remote, 1000 * 5);
-    }
-
-
-    public static SocketChannel connect(SocketAddress remote, final int timeoutMillis) {
-        SocketChannel sc = null;
-        try {
-            sc = SocketChannel.open();
-            sc.configureBlocking(true);
-            sc.socket().setSoLinger(false, -1);
-            sc.socket().setTcpNoDelay(true);
-            sc.socket().setReceiveBufferSize(1024 * 64);
-            sc.socket().setSendBufferSize(1024 * 64);
-            sc.socket().connect(remote, timeoutMillis);
-            sc.configureBlocking(false);
-            return sc;
-        } catch (Exception e) {
-            if (sc != null) {
-                try {
-                    sc.close();
-                } catch (IOException e1) {
-                    logger.error(e1.getMessage(), e1);
-                }
-            }
-        }
-
-        return null;
-    }
-
-
-    public static void closeChannel(Channel channel) {
-        final String addrRemote = RemotingHelper.parseChannelRemoteAddr(channel);
-        channel.close().addListener(new ChannelFutureListener() {
-            @Override
-            public void operationComplete(ChannelFuture future) throws Exception {
-                logger.info("closeChannel: close the connection to remote address[{}] result: {}", addrRemote,
-                        future.isSuccess());
-            }
-        });
-    }
-}

+ 0 - 1
lts-core/src/main/java/com/lts/remoting/common/SemaphoreReleaseOnlyOnce.java

@@ -11,7 +11,6 @@ public class SemaphoreReleaseOnlyOnce {
     private final AtomicBoolean released = new AtomicBoolean(false);
     private final Semaphore semaphore;
 
-
     public SemaphoreReleaseOnlyOnce(Semaphore semaphore) {
         this.semaphore = semaphore;
     }

+ 0 - 12
lts-core/src/main/java/com/lts/remoting/common/ServiceThread.java

@@ -19,36 +19,29 @@ public abstract class ServiceThread implements Runnable {
     // 线程是否已经停止
     protected volatile boolean stoped = false;
 
-
     public ServiceThread() {
         this.thread = new Thread(this, this.getServiceName());
     }
 
-
     public abstract String getServiceName();
 
-
     public void start() {
         this.thread.start();
     }
 
-
     public void shutdown() {
         this.shutdown(false);
     }
 
-
     public void stop() {
         this.stop(false);
     }
 
-
     public void makeStop() {
         this.stoped = true;
         logger.info("makestop thread " + this.getServiceName());
     }
 
-
     public void stop(final boolean interrupt) {
         this.stoped = true;
         logger.info("stop thread " + this.getServiceName() + " interrupt " + interrupt);
@@ -64,7 +57,6 @@ public abstract class ServiceThread implements Runnable {
         }
     }
 
-
     public void shutdown(final boolean interrupt) {
         this.stoped = true;
         logger.info("shutdown thread " + this.getServiceName() + " interrupt " + interrupt);
@@ -90,7 +82,6 @@ public abstract class ServiceThread implements Runnable {
         }
     }
 
-
     public void wakeup() {
         synchronized (this) {
             if (!this.hasNotified) {
@@ -100,7 +91,6 @@ public abstract class ServiceThread implements Runnable {
         }
     }
 
-
     protected void waitForRunning(long interval) {
         synchronized (this) {
             if (this.hasNotified) {
@@ -120,11 +110,9 @@ public abstract class ServiceThread implements Runnable {
         }
     }
 
-
     protected void onWaitEnd() {
     }
 
-
     public boolean isStoped() {
         return stoped;
     }

+ 75 - 0
lts-core/src/main/java/com/lts/remoting/mina/MinaChannel.java

@@ -0,0 +1,75 @@
+package com.lts.remoting.mina;
+
+import com.lts.remoting.Channel;
+import com.lts.remoting.ChannelHandler;
+import io.netty.util.internal.ThreadLocalRandom;
+import org.apache.mina.core.future.CloseFuture;
+import org.apache.mina.core.future.WriteFuture;
+import org.apache.mina.core.session.IoSession;
+
+import java.net.SocketAddress;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/4/15.
+ */
+public class MinaChannel implements Channel {
+
+    private IoSession session;
+
+    public MinaChannel(IoSession session) {
+        this.session = session;
+    }
+
+    @Override
+    public SocketAddress localAddress() {
+        return session.getLocalAddress();
+    }
+
+    @Override
+    public SocketAddress remoteAddress() {
+        return session.getRemoteAddress();
+    }
+
+    @Override
+    public ChannelHandler writeAndFlush(Object msg) {
+        WriteFuture writeFuture = session.write(msg);
+        return new MinaChannelHandler(writeFuture);
+    }
+
+    @Override
+    public ChannelHandler close() {
+        CloseFuture closeFuture = session.close(false);
+        return new MinaChannelHandler(closeFuture);
+    }
+
+    @Override
+    public boolean isConnected() {
+        return session.isConnected();
+    }
+
+    @Override
+    public boolean isOpen() {
+        return session.isConnected();
+    }
+
+    @Override
+    public boolean isClosed() {
+        return session.isClosing();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        MinaChannel that = (MinaChannel) o;
+
+        return !(session != null ? !session.equals(that.session) : that.session != null);
+
+    }
+
+    @Override
+    public int hashCode() {
+        return session != null ? session.hashCode() : 0;
+    }
+}

+ 42 - 0
lts-core/src/main/java/com/lts/remoting/mina/MinaChannelFuture.java

@@ -0,0 +1,42 @@
+package com.lts.remoting.mina;
+
+import com.lts.remoting.Channel;
+import com.lts.remoting.ChannelFuture;
+import org.apache.mina.core.future.ConnectFuture;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/4/15.
+ */
+public class MinaChannelFuture implements ChannelFuture {
+
+    private ConnectFuture connectFuture;
+
+    public MinaChannelFuture(ConnectFuture connectFuture) {
+        this.connectFuture = connectFuture;
+    }
+
+    @Override
+    public boolean isConnected() {
+        return connectFuture.isConnected();
+    }
+
+    @Override
+    public Channel getChannel() {
+        return new MinaChannel(connectFuture.getSession());
+    }
+
+    @Override
+    public boolean awaitUninterruptibly(long timeoutMillis) {
+        return connectFuture.awaitUninterruptibly(timeoutMillis);
+    }
+
+    @Override
+    public boolean isDone() {
+        return connectFuture.isDone();
+    }
+
+    @Override
+    public Throwable cause() {
+        return connectFuture.getException();
+    }
+}

+ 51 - 0
lts-core/src/main/java/com/lts/remoting/mina/MinaChannelHandler.java

@@ -0,0 +1,51 @@
+package com.lts.remoting.mina;
+
+import com.lts.remoting.ChannelHandler;
+import com.lts.remoting.ChannelHandlerListener;
+import com.lts.remoting.Future;
+import org.apache.mina.core.future.*;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/4/15.
+ */
+public class MinaChannelHandler implements ChannelHandler {
+
+    private IoFuture ioFuture;
+
+    public MinaChannelHandler(IoFuture ioFuture) {
+        this.ioFuture = ioFuture;
+    }
+
+    @Override
+    public ChannelHandler addListener(final ChannelHandlerListener listener) {
+
+        ioFuture.addListener(new IoFutureListener<IoFuture>() {
+            @Override
+            public void operationComplete(final IoFuture future) {
+                try {
+                    listener.operationComplete(new Future() {
+                        @Override
+                        public boolean isSuccess() {
+                            if (ioFuture instanceof WriteFuture) {
+                                return ((WriteFuture) future).isWritten();
+                            } else if (ioFuture instanceof ConnectFuture) {
+                                return ((ConnectFuture) future).isConnected();
+                            } else if (ioFuture instanceof CloseFuture) {
+                                return ((CloseFuture) ioFuture).isClosed();
+                            }
+                            return future.isDone();
+                        }
+
+                        @Override
+                        public Throwable cause() {
+                            return null;
+                        }
+                    });
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        return this;
+    }
+}

+ 90 - 0
lts-core/src/main/java/com/lts/remoting/mina/MinaCodecFactory.java

@@ -0,0 +1,90 @@
+package com.lts.remoting.mina;
+
+import com.lts.core.logger.Logger;
+import com.lts.core.logger.LoggerFactory;
+import com.lts.remoting.Channel;
+import com.lts.remoting.codec.Codec;
+import com.lts.remoting.common.RemotingHelper;
+import com.lts.remoting.protocol.RemotingCommand;
+import org.apache.mina.core.buffer.IoBuffer;
+import org.apache.mina.core.buffer.IoBufferAllocator;
+import org.apache.mina.core.buffer.SimpleBufferAllocator;
+import org.apache.mina.core.session.IoSession;
+import org.apache.mina.filter.codec.*;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/4/15.
+ */
+public class MinaCodecFactory implements ProtocolCodecFactory {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(RemotingHelper.RemotingLogName);
+
+    private Codec codec;
+
+    public MinaCodecFactory(Codec codec) {
+        this.codec = codec;
+    }
+
+    @Override
+    public ProtocolEncoder getEncoder(IoSession session) throws Exception {
+        return encoder;
+    }
+
+    @Override
+    public ProtocolDecoder getDecoder(IoSession session) throws Exception {
+        return decoder;
+    }
+
+    IoBufferAllocator bufferAllocator = new SimpleBufferAllocator();
+
+    private ProtocolEncoder encoder = new ProtocolEncoderAdapter() {
+
+        @Override
+        public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
+            if (message == null) {
+                LOGGER.error("Message is null");
+                return;
+            }
+            if (!(message instanceof RemotingCommand)) {
+                LOGGER.error("{} is not instanceof RemotingCommand", message);
+                return;
+            }
+            RemotingCommand remotingCommand = (RemotingCommand) message;
+
+            try {
+                ByteBuffer byteBuffer = codec.encode(remotingCommand);
+                IoBuffer ioBuffer = bufferAllocator.wrap(byteBuffer);
+                out.write(ioBuffer);
+                out.flush();
+            } catch (Exception e) {
+                Channel channel = new MinaChannel(session);
+                LOGGER.error("encode exception, addr={}, remotingCommand={}", RemotingHelper.parseChannelRemoteAddr(channel), remotingCommand.toString(), e);
+                RemotingHelper.closeChannel(channel);
+                throw e;
+            }
+        }
+    };
+
+    private ProtocolDecoder decoder = new CumulativeProtocolDecoder() {
+
+        @Override
+        protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
+            try {
+                // TODO 
+                in.order(ByteOrder.BIG_ENDIAN);
+                RemotingCommand remotingCommand = codec.decode(in.buf());
+                out.write(remotingCommand);
+            } catch (Exception e) {
+                Channel channel = new MinaChannel(session);
+                LOGGER.error("decode exception, {}", RemotingHelper.parseChannelRemoteAddr(channel), e);
+                RemotingHelper.closeChannel(channel);
+                throw e;
+            }
+            return true;
+        }
+    };
+
+}

+ 354 - 0
lts-core/src/main/java/com/lts/remoting/mina/MinaLogger.java

@@ -0,0 +1,354 @@
+package com.lts.remoting.mina;
+
+import com.lts.core.logger.Logger;
+import com.lts.core.logger.LoggerFactory;
+import org.apache.mina.core.filterchain.IoFilterAdapter;
+import org.apache.mina.core.session.IdleStatus;
+import org.apache.mina.core.session.IoSession;
+import org.apache.mina.core.write.WriteRequest;
+import org.apache.mina.filter.logging.LogLevel;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/4/15.
+ */
+public class MinaLogger extends IoFilterAdapter {
+    /**
+     * The logger name
+     */
+    private final String name;
+
+    /**
+     * The logger
+     */
+    private final Logger logger;
+
+    /**
+     * The log level for the exceptionCaught event. Default to WARN.
+     */
+    private LogLevel exceptionCaughtLevel = LogLevel.WARN;
+
+    /**
+     * The log level for the messageSent event. Default to INFO.
+     */
+    private LogLevel messageSentLevel = LogLevel.INFO;
+
+    /**
+     * The log level for the messageReceived event. Default to INFO.
+     */
+    private LogLevel messageReceivedLevel = LogLevel.INFO;
+
+    /**
+     * The log level for the sessionCreated event. Default to INFO.
+     */
+    private LogLevel sessionCreatedLevel = LogLevel.INFO;
+
+    /**
+     * The log level for the sessionOpened event. Default to INFO.
+     */
+    private LogLevel sessionOpenedLevel = LogLevel.INFO;
+
+    /**
+     * The log level for the sessionIdle event. Default to INFO.
+     */
+    private LogLevel sessionIdleLevel = LogLevel.INFO;
+
+    /**
+     * The log level for the sessionClosed event. Default to INFO.
+     */
+    private LogLevel sessionClosedLevel = LogLevel.INFO;
+
+    /**
+     * Default Constructor.
+     */
+    public MinaLogger() {
+        this(MinaLogger.class.getName());
+    }
+
+    /**
+     * Create a new NoopFilter using a class name
+     *
+     * @param clazz the cass which name will be used to create the logger
+     */
+    public MinaLogger(Class<?> clazz) {
+        this(clazz.getName());
+    }
+
+    /**
+     * Create a new NoopFilter using a name
+     *
+     * @param name the name used to create the logger. If null, will default to "NoopFilter"
+     */
+    public MinaLogger(String name) {
+        if (name == null) {
+            this.name = MinaLogger.class.getName();
+        } else {
+            this.name = name;
+        }
+
+        logger = LoggerFactory.getLogger(this.name);
+    }
+
+    /**
+     * @return The logger's name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Log if the logger and the current event log level are compatible. We log
+     * a message and an exception.
+     *
+     * @param eventLevel the event log level as requested by the user
+     * @param message    the message to log
+     * @param cause      the exception cause to log
+     */
+    private void log(LogLevel eventLevel, String message, Throwable cause) {
+        switch (eventLevel) {
+            case TRACE:
+                logger.trace(message, cause);
+                return;
+            case DEBUG:
+                logger.debug(message, cause);
+                return;
+            case INFO:
+                logger.info(message, cause);
+                return;
+            case WARN:
+                logger.warn(message, cause);
+                return;
+            case ERROR:
+                logger.error(message, cause);
+                return;
+            default:
+                return;
+        }
+    }
+
+    /**
+     * Log if the logger and the current event log level are compatible. We log
+     * a formated message and its parameters.
+     *
+     * @param eventLevel the event log level as requested by the user
+     * @param message    the formated message to log
+     * @param param      the parameter injected into the message
+     */
+    private void log(LogLevel eventLevel, String message, Object param) {
+        switch (eventLevel) {
+            case TRACE:
+                logger.trace(message, param);
+                return;
+            case DEBUG:
+                logger.debug(message, param);
+                return;
+            case INFO:
+                logger.info(message, param);
+                return;
+            case WARN:
+                logger.warn(message, param);
+                return;
+            case ERROR:
+                logger.error(message, param);
+                return;
+            default:
+                return;
+        }
+    }
+
+    /**
+     * Log if the logger and the current event log level are compatible. We log
+     * a simple message.
+     *
+     * @param eventLevel the event log level as requested by the user
+     * @param message    the message to log
+     */
+    private void log(LogLevel eventLevel, String message) {
+        switch (eventLevel) {
+            case TRACE:
+                logger.trace(message);
+                return;
+            case DEBUG:
+                logger.debug(message);
+                return;
+            case INFO:
+                logger.info(message);
+                return;
+            case WARN:
+                logger.warn(message);
+                return;
+            case ERROR:
+                logger.error(message);
+                return;
+            default:
+                return;
+        }
+    }
+
+    @Override
+    public void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) throws Exception {
+        log(exceptionCaughtLevel, "EXCEPTION :", cause);
+        nextFilter.exceptionCaught(session, cause);
+    }
+
+    @Override
+    public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
+        log(messageReceivedLevel, "RECEIVED: {}", message);
+        nextFilter.messageReceived(session, message);
+    }
+
+    @Override
+    public void messageSent(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception {
+        log(messageSentLevel, "SENT: {}", writeRequest.getOriginalRequest().getMessage());
+        nextFilter.messageSent(session, writeRequest);
+    }
+
+    @Override
+    public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception {
+        log(sessionCreatedLevel, "CREATED");
+        nextFilter.sessionCreated(session);
+    }
+
+    @Override
+    public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception {
+        log(sessionOpenedLevel, "OPENED");
+        nextFilter.sessionOpened(session);
+    }
+
+    @Override
+    public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception {
+        log(sessionIdleLevel, "IDLE");
+        nextFilter.sessionIdle(session, status);
+    }
+
+    @Override
+    public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception {
+        log(sessionClosedLevel, "CLOSED");
+        nextFilter.sessionClosed(session);
+    }
+
+    /**
+     * Set the LogLevel for the ExceptionCaught event.
+     *
+     * @param level The LogLevel to set
+     */
+    public void setExceptionCaughtLogLevel(LogLevel level) {
+        exceptionCaughtLevel = level;
+    }
+
+    /**
+     * Get the LogLevel for the ExceptionCaught event.
+     *
+     * @return The LogLevel for the ExceptionCaught eventType
+     */
+    public LogLevel getExceptionCaughtLogLevel() {
+        return exceptionCaughtLevel;
+    }
+
+    /**
+     * Set the LogLevel for the MessageReceived event.
+     *
+     * @param level The LogLevel to set
+     */
+    public void setMessageReceivedLogLevel(LogLevel level) {
+        messageReceivedLevel = level;
+    }
+
+    /**
+     * Get the LogLevel for the MessageReceived event.
+     *
+     * @return The LogLevel for the MessageReceived eventType
+     */
+    public LogLevel getMessageReceivedLogLevel() {
+        return messageReceivedLevel;
+    }
+
+    /**
+     * Set the LogLevel for the MessageSent event.
+     *
+     * @param level The LogLevel to set
+     */
+    public void setMessageSentLogLevel(LogLevel level) {
+        messageSentLevel = level;
+    }
+
+    /**
+     * Get the LogLevel for the MessageSent event.
+     *
+     * @return The LogLevel for the MessageSent eventType
+     */
+    public LogLevel getMessageSentLogLevel() {
+        return messageSentLevel;
+    }
+
+    /**
+     * Set the LogLevel for the SessionCreated event.
+     *
+     * @param level The LogLevel to set
+     */
+    public void setSessionCreatedLogLevel(LogLevel level) {
+        sessionCreatedLevel = level;
+    }
+
+    /**
+     * Get the LogLevel for the SessionCreated event.
+     *
+     * @return The LogLevel for the SessionCreated eventType
+     */
+    public LogLevel getSessionCreatedLogLevel() {
+        return sessionCreatedLevel;
+    }
+
+    /**
+     * Set the LogLevel for the SessionOpened event.
+     *
+     * @param level The LogLevel to set
+     */
+    public void setSessionOpenedLogLevel(LogLevel level) {
+        sessionOpenedLevel = level;
+    }
+
+    /**
+     * Get the LogLevel for the SessionOpened event.
+     *
+     * @return The LogLevel for the SessionOpened eventType
+     */
+    public LogLevel getSessionOpenedLogLevel() {
+        return sessionOpenedLevel;
+    }
+
+    /**
+     * Set the LogLevel for the SessionIdle event.
+     *
+     * @param level The LogLevel to set
+     */
+    public void setSessionIdleLogLevel(LogLevel level) {
+        sessionIdleLevel = level;
+    }
+
+    /**
+     * Get the LogLevel for the SessionIdle event.
+     *
+     * @return The LogLevel for the SessionIdle eventType
+     */
+    public LogLevel getSessionIdleLogLevel() {
+        return sessionIdleLevel;
+    }
+
+    /**
+     * Set the LogLevel for the SessionClosed event.
+     *
+     * @param level The LogLevel to set
+     */
+    public void setSessionClosedLogLevel(LogLevel level) {
+        sessionClosedLevel = level;
+    }
+
+    /**
+     * Get the LogLevel for the SessionClosed event.
+     *
+     * @return The LogLevel for the SessionClosed eventType
+     */
+    public LogLevel getSessionClosedLogLevel() {
+        return sessionClosedLevel;
+    }
+}

+ 155 - 0
lts-core/src/main/java/com/lts/remoting/mina/MinaRemotingClient.java

@@ -0,0 +1,155 @@
+package com.lts.remoting.mina;
+
+import com.lts.remoting.*;
+import com.lts.remoting.common.RemotingHelper;
+import com.lts.remoting.exception.RemotingException;
+import com.lts.remoting.protocol.RemotingCommand;
+import org.apache.mina.core.future.ConnectFuture;
+import org.apache.mina.core.service.IoHandlerAdapter;
+import org.apache.mina.core.session.IdleStatus;
+import org.apache.mina.core.session.IoSession;
+import org.apache.mina.core.session.IoSessionConfig;
+import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.mina.filter.logging.MdcInjectionFilter;
+import org.apache.mina.transport.socket.nio.NioSocketConnector;
+
+import java.net.SocketAddress;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/4/15.
+ */
+public class MinaRemotingClient extends AbstractRemotingClient {
+
+    private NioSocketConnector connector;
+
+    public MinaRemotingClient(RemotingClientConfig remotingClientConfig) {
+        this(remotingClientConfig, null);
+    }
+
+    public MinaRemotingClient(RemotingClientConfig remotingClientConfig, ChannelEventListener channelEventListener) {
+        super(remotingClientConfig, channelEventListener);
+    }
+
+    @Override
+    protected void clientStart() throws RemotingException {
+        try {
+            connector = new NioSocketConnector(); //TCP Connector
+
+//            connector.getFilterChain().addFirst("logging", new MinaLoggingFilter());
+            connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MinaCodecFactory(getCodec())));
+            connector.getFilterChain().addLast("mdc", new MdcInjectionFilter());
+
+            connector.setHandler(new MinaHandler());
+            IoSessionConfig cfg = connector.getSessionConfig();
+            cfg.setReaderIdleTime(remotingClientConfig.getReaderIdleTimeSeconds());
+            cfg.setWriterIdleTime(remotingClientConfig.getWriterIdleTimeSeconds());
+            cfg.setBothIdleTime(remotingClientConfig.getClientChannelMaxIdleTimeSeconds());
+        } catch (Exception e) {
+            throw new RemotingException("Mina Client start error", e);
+        }
+    }
+
+    @Override
+    protected void clientShutdown() {
+        if (connector != null) {
+            connector.dispose();
+        }
+    }
+
+    @Override
+    protected ChannelFuture connect(SocketAddress socketAddress) {
+        ConnectFuture connectFuture = connector.connect(socketAddress);
+        return new MinaChannelFuture(connectFuture);
+    }
+
+    class MinaHandler extends IoHandlerAdapter {
+
+        @Override
+        public void sessionCreated(IoSession session) throws Exception {
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(new MinaChannel(session));
+            LOGGER.info("CLIENT : sessionCreated {}", remoteAddress);
+            super.sessionCreated(session);
+        }
+
+        @Override
+        public void sessionOpened(IoSession session) throws Exception {
+            Channel channel = new MinaChannel(session);
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
+            LOGGER.info("CLIENT: sessionOpened, the channel[{}]", remoteAddress);
+
+            if (channelEventListener != null) {
+                putRemotingEvent(new RemotingEvent(RemotingEventType.CONNECT, remoteAddress, channel));
+            }
+        }
+
+        @Override
+        public void sessionClosed(IoSession session) throws Exception {
+            com.lts.remoting.Channel channel = new MinaChannel(session);
+
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
+            LOGGER.info("CLIENT: sessionClosed, the channel[{}]", remoteAddress);
+
+            if (channelEventListener != null) {
+                putRemotingEvent(new RemotingEvent(RemotingEventType.CLOSE, remoteAddress, channel));
+            }
+        }
+
+        @Override
+        public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
+            com.lts.remoting.Channel channel = new MinaChannel(session);
+
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
+
+            if (IdleStatus.BOTH_IDLE == status) {
+                LOGGER.warn("CLIENT: IDLE [{}]", remoteAddress);
+                RemotingHelper.closeChannel(channel);
+            }
+
+            if (channelEventListener != null) {
+                RemotingEventType remotingEventType = null;
+                if (IdleStatus.BOTH_IDLE == status) {
+                    remotingEventType = RemotingEventType.ALL_IDLE;
+                } else if (IdleStatus.READER_IDLE == status) {
+                    remotingEventType = RemotingEventType.READER_IDLE;
+                } else if (IdleStatus.WRITER_IDLE == status) {
+                    remotingEventType = RemotingEventType.WRITER_IDLE;
+                }
+                putRemotingEvent(new RemotingEvent(remotingEventType,
+                        remoteAddress, channel));
+            }
+        }
+
+        @Override
+        public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
+            com.lts.remoting.Channel channel = new MinaChannel(session);
+
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
+            LOGGER.warn("CLIENT: exceptionCaught {}", remoteAddress);
+            LOGGER.warn("CLIENT: exceptionCaught exception.", cause);
+
+            if (channelEventListener != null) {
+                putRemotingEvent(new RemotingEvent(RemotingEventType.EXCEPTION, remoteAddress, channel));
+            }
+
+            RemotingHelper.closeChannel(channel);
+        }
+
+        @Override
+        public void messageReceived(IoSession session, Object message) throws Exception {
+            if (message != null && message instanceof RemotingCommand) {
+                processMessageReceived(new MinaChannel(session), (RemotingCommand) message);
+            }
+        }
+
+        @Override
+        public void messageSent(IoSession session, Object message) throws Exception {
+            LOGGER.warn("CLIENT: messageSent {}", message);
+        }
+
+        @Override
+        public void inputClosed(IoSession session) throws Exception {
+            LOGGER.warn("CLIENT: inputClosed");
+            session.close(true);
+        }
+    }
+}

+ 157 - 0
lts-core/src/main/java/com/lts/remoting/mina/MinaRemotingServer.java

@@ -0,0 +1,157 @@
+package com.lts.remoting.mina;
+
+import com.lts.remoting.*;
+import com.lts.remoting.common.RemotingHelper;
+import com.lts.remoting.exception.RemotingException;
+import com.lts.remoting.protocol.RemotingCommand;
+import org.apache.mina.core.service.IoAcceptor;
+import org.apache.mina.core.service.IoHandlerAdapter;
+import org.apache.mina.core.session.IdleStatus;
+import org.apache.mina.core.session.IoSession;
+import org.apache.mina.core.session.IoSessionConfig;
+import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.mina.filter.logging.MdcInjectionFilter;
+import org.apache.mina.transport.socket.nio.NioProcessor;
+import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/4/15.
+ */
+public class MinaRemotingServer extends AbstractRemotingServer {
+
+    private IoAcceptor acceptor;
+    private InetSocketAddress bindAddress;
+
+    public MinaRemotingServer(RemotingServerConfig remotingServerConfig) {
+        this(remotingServerConfig, null);
+    }
+
+    public MinaRemotingServer(RemotingServerConfig remotingServerConfig, ChannelEventListener channelEventListener) {
+        super(remotingServerConfig, channelEventListener);
+    }
+
+    @Override
+    protected void serverStart() throws RemotingException {
+        int executor;
+        acceptor = new NioSocketAcceptor(); //TCP Acceptor
+
+//        acceptor.getFilterChain().addFirst("logging", new MinaLoggingFilter());
+        acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MinaCodecFactory(getCodec())));
+        acceptor.getFilterChain().addLast("mdc", new MdcInjectionFilter());
+
+        acceptor.setHandler(new MinaHandler());
+        IoSessionConfig cfg = acceptor.getSessionConfig();
+        cfg.setReaderIdleTime(remotingServerConfig.getReaderIdleTimeSeconds());
+        cfg.setWriterIdleTime(remotingServerConfig.getWriterIdleTimeSeconds());
+        cfg.setBothIdleTime(remotingServerConfig.getServerChannelMaxIdleTimeSeconds());
+
+        bindAddress = new InetSocketAddress(remotingServerConfig.getListenPort());
+        try {
+            acceptor.bind(bindAddress);
+        } catch (IOException e) {
+            throw new RemotingException("Start Mina server error", e);
+        }
+    }
+
+    @Override
+    protected void serverShutdown() {
+        if (acceptor != null) {
+            acceptor.unbind(bindAddress);
+            acceptor.dispose();
+        }
+    }
+
+    class MinaHandler extends IoHandlerAdapter {
+
+        @Override
+        public void sessionCreated(IoSession session) throws Exception {
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(new MinaChannel(session));
+            LOGGER.info("SERVER : sessionCreated {}", remoteAddress);
+            super.sessionCreated(session);
+        }
+
+        @Override
+        public void sessionOpened(IoSession session) throws Exception {
+            Channel channel = new MinaChannel(session);
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
+            LOGGER.info("SERVER: sessionOpened, the channel[{}]", remoteAddress);
+
+            if (channelEventListener != null) {
+                putRemotingEvent(new RemotingEvent(RemotingEventType.CONNECT, remoteAddress, channel));
+            }
+        }
+
+        @Override
+        public void sessionClosed(IoSession session) throws Exception {
+            com.lts.remoting.Channel channel = new MinaChannel(session);
+
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
+            LOGGER.info("SERVER: sessionClosed, the channel[{}]", remoteAddress);
+
+            if (channelEventListener != null) {
+                putRemotingEvent(new RemotingEvent(RemotingEventType.CLOSE, remoteAddress, channel));
+            }
+        }
+
+        @Override
+        public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
+            com.lts.remoting.Channel channel = new MinaChannel(session);
+
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
+
+            if (IdleStatus.BOTH_IDLE == status) {
+                LOGGER.warn("SERVER: IDLE [{}]", remoteAddress);
+                RemotingHelper.closeChannel(channel);
+            }
+
+            if (channelEventListener != null) {
+                RemotingEventType remotingEventType = null;
+                if (IdleStatus.BOTH_IDLE == status) {
+                    remotingEventType = RemotingEventType.ALL_IDLE;
+                } else if (IdleStatus.READER_IDLE == status) {
+                    remotingEventType = RemotingEventType.READER_IDLE;
+                } else if (IdleStatus.WRITER_IDLE == status) {
+                    remotingEventType = RemotingEventType.WRITER_IDLE;
+                }
+                putRemotingEvent(new RemotingEvent(remotingEventType,
+                        remoteAddress, channel));
+            }
+        }
+
+        @Override
+        public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
+            com.lts.remoting.Channel channel = new MinaChannel(session);
+
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
+            LOGGER.warn("SERVER: exceptionCaught {}", remoteAddress);
+            LOGGER.warn("SERVER: exceptionCaught exception.", cause);
+
+            if (channelEventListener != null) {
+                putRemotingEvent(new RemotingEvent(RemotingEventType.EXCEPTION, remoteAddress, channel));
+            }
+
+            RemotingHelper.closeChannel(channel);
+        }
+
+        @Override
+        public void messageReceived(IoSession session, Object message) throws Exception {
+            if (message != null && message instanceof RemotingCommand) {
+                processMessageReceived(new MinaChannel(session), (RemotingCommand) message);
+            }
+        }
+
+        @Override
+        public void messageSent(IoSession session, Object message) throws Exception {
+            LOGGER.warn("SERVER: messageSent {}", message);
+        }
+
+        @Override
+        public void inputClosed(IoSession session) throws Exception {
+            LOGGER.warn("SERVER: inputClosed");
+            session.close(true);
+        }
+    }
+}

+ 76 - 0
lts-core/src/main/java/com/lts/remoting/netty/NettyChannel.java

@@ -0,0 +1,76 @@
+package com.lts.remoting.netty;
+
+
+import com.lts.remoting.ChannelHandler;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandlerContext;
+
+import java.net.SocketAddress;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/3/15.
+ */
+public class NettyChannel implements com.lts.remoting.Channel {
+
+    private Channel channel;
+
+    public NettyChannel(ChannelHandlerContext ctx) {
+        this.channel = ctx.channel();
+    }
+
+    public NettyChannel(Channel channel) {
+        this.channel = channel;
+    }
+
+    @Override
+    public SocketAddress localAddress() {
+        return channel.localAddress();
+    }
+
+    @Override
+    public SocketAddress remoteAddress() {
+        return channel.remoteAddress();
+    }
+
+    @Override
+    public ChannelHandler writeAndFlush(Object msg) {
+        ChannelFuture channelFuture = channel.writeAndFlush(msg);
+        return new NettyChannelHandler(channelFuture);
+    }
+
+    @Override
+    public ChannelHandler close() {
+        return new NettyChannelHandler(channel.close());
+    }
+
+    public boolean isConnected() {
+        return channel.isActive();
+    }
+
+    @Override
+    public boolean isOpen() {
+        return channel.isOpen();
+    }
+
+    @Override
+    public boolean isClosed() {
+        return !isOpen();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        NettyChannel that = (NettyChannel) o;
+
+        return !(channel != null ? !channel.equals(that.channel) : that.channel != null);
+
+    }
+
+    @Override
+    public int hashCode() {
+        return channel != null ? channel.hashCode() : 0;
+    }
+}

+ 41 - 0
lts-core/src/main/java/com/lts/remoting/netty/NettyChannelFuture.java

@@ -0,0 +1,41 @@
+package com.lts.remoting.netty;
+
+import com.lts.remoting.Channel;
+import com.lts.remoting.ChannelFuture;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/4/15.
+ */
+public class NettyChannelFuture implements ChannelFuture {
+
+    private io.netty.channel.ChannelFuture channelFuture;
+
+    public NettyChannelFuture(io.netty.channel.ChannelFuture channelFuture) {
+        this.channelFuture = channelFuture;
+    }
+
+    @Override
+    public boolean isConnected() {
+        return channelFuture.channel() != null && channelFuture.channel().isActive();
+    }
+
+    @Override
+    public Channel getChannel() {
+        return new NettyChannel(channelFuture.channel());
+    }
+
+    @Override
+    public boolean awaitUninterruptibly(long timeoutMillis) {
+        return channelFuture.awaitUninterruptibly(timeoutMillis);
+    }
+
+    @Override
+    public boolean isDone() {
+        return channelFuture.isDone();
+    }
+
+    @Override
+    public Throwable cause() {
+        return channelFuture.cause();
+    }
+}

+ 42 - 0
lts-core/src/main/java/com/lts/remoting/netty/NettyChannelHandler.java

@@ -0,0 +1,42 @@
+package com.lts.remoting.netty;
+
+import com.lts.remoting.ChannelHandler;
+import com.lts.remoting.ChannelHandlerListener;
+import com.lts.remoting.Future;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/3/15.
+ */
+public class NettyChannelHandler implements ChannelHandler {
+
+    private ChannelFuture channelFuture;
+
+    public NettyChannelHandler(ChannelFuture channelFuture) {
+        this.channelFuture = channelFuture;
+    }
+
+    @Override
+    public ChannelHandler addListener(final ChannelHandlerListener listener) {
+
+        channelFuture.addListener(new ChannelFutureListener() {
+            @Override
+            public void operationComplete(final ChannelFuture future) throws Exception {
+                listener.operationComplete(new Future() {
+                    @Override
+                    public boolean isSuccess() {
+                        return future.isSuccess();
+                    }
+
+                    @Override
+                    public Throwable cause() {
+                        return future.cause();
+                    }
+                });
+            }
+        });
+
+        return this;
+    }
+}

+ 95 - 0
lts-core/src/main/java/com/lts/remoting/netty/NettyCodecFactory.java

@@ -0,0 +1,95 @@
+package com.lts.remoting.netty;
+
+import com.lts.core.logger.Logger;
+import com.lts.core.logger.LoggerFactory;
+import com.lts.remoting.Channel;
+import com.lts.remoting.codec.Codec;
+import com.lts.remoting.common.RemotingHelper;
+import com.lts.remoting.protocol.RemotingCommand;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
+import io.netty.handler.codec.MessageToByteEncoder;
+
+import java.nio.ByteBuffer;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/5/15.
+ */
+public class NettyCodecFactory {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(RemotingHelper.RemotingLogName);
+
+    private Codec codec;
+
+    public NettyCodecFactory(Codec codec) {
+        this.codec = codec;
+    }
+
+    private ChannelHandler encoder = new NettyEncoder();
+
+    private ChannelHandler decoder = new NettyDecoder();
+
+    class NettyEncoder extends MessageToByteEncoder<RemotingCommand> {
+        @Override
+        public void encode(ChannelHandlerContext ctx, RemotingCommand remotingCommand, ByteBuf out)
+                throws Exception {
+
+            if (remotingCommand == null) {
+                LOGGER.error("Message is null");
+                return;
+            }
+
+            try {
+                ByteBuffer byteBuffer = codec.encode(remotingCommand);
+                out.writeBytes(byteBuffer);
+            } catch (Exception e) {
+                Channel channel = new NettyChannel(ctx);
+                LOGGER.error("encode exception, addr={}, remotingCommand={}", RemotingHelper.parseChannelRemoteAddr(channel), remotingCommand.toString(), e);
+                RemotingHelper.closeChannel(channel);
+            }
+        }
+    }
+
+    class NettyDecoder extends LengthFieldBasedFrameDecoder {
+
+        private static final int FRAME_MAX_LENGTH = 1024 * 1024 * 8;
+
+        public NettyDecoder() {
+            super(FRAME_MAX_LENGTH, 0, 4, 0, 4);
+        }
+
+        @Override
+        public Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
+            try {
+                ByteBuf frame = (ByteBuf) super.decode(ctx, in);
+                if (frame == null) {
+                    return null;
+                }
+
+                byte[] tmpBuf = new byte[frame.capacity()];
+                frame.getBytes(0, tmpBuf);
+                frame.release();
+
+                ByteBuffer byteBuffer = ByteBuffer.wrap(tmpBuf);
+                return codec.decode(byteBuffer);
+            } catch (Exception e) {
+                Channel channel = new NettyChannel(ctx);
+                LOGGER.error("decode exception, {}", RemotingHelper.parseChannelRemoteAddr(channel), e);
+                // 这里关闭后, 会在pipeline中产生事件,通过具体的close事件来清理数据结构
+                RemotingHelper.closeChannel(channel);
+            }
+
+            return null;
+        }
+    }
+
+    public ChannelHandler getEncoder() {
+        return encoder;
+    }
+
+    public ChannelHandler getDecoder() {
+        return decoder;
+    }
+}

+ 0 - 47
lts-core/src/main/java/com/lts/remoting/netty/NettyDecoder.java

@@ -1,47 +0,0 @@
-package com.lts.remoting.netty;
-
-import com.lts.core.logger.Logger;
-import com.lts.core.logger.LoggerFactory;
-import com.lts.remoting.common.RemotingHelper;
-import com.lts.remoting.common.RemotingUtil;
-import com.lts.remoting.protocol.RemotingCommand;
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
-
-
-/**
- * 协议解码器
- */
-public class NettyDecoder extends LengthFieldBasedFrameDecoder {
-    private static final Logger LOGGER = LoggerFactory.getLogger(RemotingHelper.RemotingLogName);
-    private static final int FRAME_MAX_LENGTH = 1024 * 1024 * 8;
-
-
-    public NettyDecoder() {
-        super(FRAME_MAX_LENGTH, 0, 4, 0, 4);
-    }
-
-
-    @Override
-    public Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
-        try {
-            ByteBuf frame = (ByteBuf) super.decode(ctx, in);
-            if (frame == null) {
-                return null;
-            }
-
-            byte[] tmpBuf = new byte[frame.capacity()];
-            frame.getBytes(0, tmpBuf);
-            frame.release();
-
-            return RemotingCommand.decode(tmpBuf);
-        } catch (Exception e) {
-            LOGGER.error("decode exception, {}", RemotingHelper.parseChannelRemoteAddr(ctx.channel()), e);
-            // 这里关闭后, 会在pipeline中产生事件,通过具体的close事件来清理数据结构
-            RemotingUtil.closeChannel(ctx.channel());
-        }
-
-        return null;
-    }
-}

+ 0 - 37
lts-core/src/main/java/com/lts/remoting/netty/NettyEncoder.java

@@ -1,37 +0,0 @@
-package com.lts.remoting.netty;
-
-import com.lts.core.logger.Logger;
-import com.lts.core.logger.LoggerFactory;
-import com.lts.remoting.common.RemotingHelper;
-import com.lts.remoting.common.RemotingUtil;
-import com.lts.remoting.protocol.RemotingCommand;
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.MessageToByteEncoder;
-
-import java.nio.ByteBuffer;
-
-
-/**
- * 协议编码器
- */
-public class NettyEncoder extends MessageToByteEncoder<RemotingCommand> {
-    private static final Logger log = LoggerFactory.getLogger(RemotingHelper.RemotingLogName);
-
-
-    @Override
-    public void encode(ChannelHandlerContext ctx, RemotingCommand remotingCommand, ByteBuf out)
-            throws Exception {
-        try {
-            ByteBuffer byteBuffer = remotingCommand.encode();
-            out.writeBytes(byteBuffer);
-        } catch (Exception e) {
-            log.error("encode exception, " + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), e);
-            if (remotingCommand != null) {
-                log.error(remotingCommand.toString());
-            }
-            // 这里关闭后, 会在pipeline中产生事件,通过具体的close事件来清理数据结构
-            RemotingUtil.closeChannel(ctx.channel());
-        }
-    }
-}

+ 333 - 0
lts-core/src/main/java/com/lts/remoting/netty/NettyLogger.java

@@ -0,0 +1,333 @@
+package com.lts.remoting.netty;
+
+import com.lts.core.logger.Logger;
+import com.lts.core.logger.LoggerFactory;
+import io.netty.util.internal.logging.InternalLogLevel;
+import io.netty.util.internal.logging.InternalLogger;
+import io.netty.util.internal.logging.InternalLoggerFactory;
+
+/**
+ * @author Robert HG (254963746@qq.com) on 11/5/15.
+ */
+public class NettyLogger {
+
+    public static void setNettyLoggerFactory() {
+        InternalLoggerFactory factory = InternalLoggerFactory.getDefaultFactory();
+        if (factory == null || !(factory instanceof LtsLoggerFactory)) {
+            InternalLoggerFactory.setDefaultFactory(new LtsLoggerFactory());
+        }
+    }
+
+    private static class LtsLoggerFactory extends InternalLoggerFactory {
+        @Override
+        protected InternalLogger newInstance(String name) {
+            return new LtsLogger(name);
+        }
+    }
+
+    static class LtsLogger implements InternalLogger {
+
+        private Logger logger;
+        private String name;
+
+        LtsLogger(String name) {
+            this.name = name;
+            this.logger = LoggerFactory.getLogger(name);
+        }
+
+        @Override
+        public String name() {
+            return name;
+        }
+
+        @Override
+        public boolean isTraceEnabled() {
+            return logger.isTraceEnabled();
+        }
+
+        @Override
+        public void trace(String msg) {
+            logger.trace(msg);
+        }
+
+        @Override
+        public void trace(String format, Object arg) {
+            logger.trace(format, arg);
+        }
+
+        @Override
+        public void trace(String format, Object argA, Object argB) {
+            logger.trace(format, argA, argB);
+        }
+
+        @Override
+        public void trace(String format, Object... arguments) {
+            logger.trace(format, arguments);
+        }
+
+        @Override
+        public void trace(String msg, Throwable t) {
+            logger.trace(msg, t);
+        }
+
+        @Override
+        public boolean isDebugEnabled() {
+            return logger.isDebugEnabled();
+        }
+
+        @Override
+        public void debug(String msg) {
+            logger.debug(msg);
+        }
+
+        @Override
+        public void debug(String format, Object arg) {
+            logger.debug(format, arg);
+        }
+
+        @Override
+        public void debug(String format, Object argA, Object argB) {
+            logger.debug(format, argA, argB);
+        }
+
+        @Override
+        public void debug(String format, Object... arguments) {
+            logger.debug(format, arguments);
+        }
+
+        @Override
+        public void debug(String msg, Throwable t) {
+            logger.debug(msg, t);
+        }
+
+        @Override
+        public boolean isInfoEnabled() {
+            return logger.isInfoEnabled();
+        }
+
+        @Override
+        public void info(String msg) {
+            logger.info(msg);
+        }
+
+        @Override
+        public void info(String format, Object arg) {
+            logger.info(format, arg);
+        }
+
+        @Override
+        public void info(String format, Object argA, Object argB) {
+            logger.info(format, argA, argB);
+        }
+
+        @Override
+        public void info(String format, Object... arguments) {
+            logger.info(format, arguments);
+        }
+
+        @Override
+        public void info(String msg, Throwable t) {
+            logger.info(msg, t);
+        }
+
+        @Override
+        public boolean isWarnEnabled() {
+            return logger.isWarnEnabled();
+        }
+
+        @Override
+        public void warn(String msg) {
+            logger.warn(msg);
+        }
+
+        @Override
+        public void warn(String format, Object arg) {
+            logger.warn(format, arg);
+        }
+
+        @Override
+        public void warn(String format, Object... arguments) {
+            logger.warn(format, arguments);
+        }
+
+        @Override
+        public void warn(String format, Object argA, Object argB) {
+            logger.warn(format, argA, argB);
+        }
+
+        @Override
+        public void warn(String msg, Throwable t) {
+            logger.warn(msg, t);
+        }
+
+        @Override
+        public boolean isErrorEnabled() {
+            return logger.isErrorEnabled();
+        }
+
+        @Override
+        public void error(String msg) {
+            logger.error(msg);
+        }
+
+        @Override
+        public void error(String format, Object arg) {
+            logger.error(format, arg);
+        }
+
+        @Override
+        public void error(String format, Object argA, Object argB) {
+            logger.error(format, argA, argB);
+        }
+
+        @Override
+        public void error(String format, Object... arguments) {
+            logger.error(format, arguments);
+        }
+
+        @Override
+        public void error(String msg, Throwable t) {
+            logger.error(msg, t);
+        }
+
+        @Override
+        public boolean isEnabled(InternalLogLevel level) {
+            if (level == null) {
+                return false;
+            }
+            switch (level) {
+                case TRACE:
+                    return logger.isTraceEnabled();
+                case DEBUG:
+                    return logger.isDebugEnabled();
+                case INFO:
+                    return logger.isInfoEnabled();
+                case WARN:
+                    return logger.isWarnEnabled();
+                case ERROR:
+                    return logger.isErrorEnabled();
+            }
+            return false;
+        }
+
+        @Override
+        public void log(InternalLogLevel level, String msg) {
+            if (level == null) {
+                return;
+            }
+            switch (level) {
+                case TRACE:
+                    trace(msg);
+                    break;
+                case DEBUG:
+                    debug(msg);
+                    break;
+                case INFO:
+                    info(msg);
+                    break;
+                case WARN:
+                    warn(msg);
+                    break;
+                case ERROR:
+                    error(msg);
+                    break;
+            }
+        }
+
+        @Override
+        public void log(InternalLogLevel level, String format, Object arg) {
+            if (level == null) {
+                return;
+            }
+            switch (level) {
+                case TRACE:
+                    trace(format, arg);
+                    break;
+                case DEBUG:
+                    debug(format, arg);
+                    break;
+                case INFO:
+                    info(format, arg);
+                    break;
+                case WARN:
+                    warn(format, arg);
+                    break;
+                case ERROR:
+                    error(format, arg);
+                    break;
+            }
+        }
+
+        @Override
+        public void log(InternalLogLevel level, String format, Object argA, Object argB) {
+            if (level == null) {
+                return;
+            }
+            switch (level) {
+                case TRACE:
+                    trace(format, argA, argB);
+                    break;
+                case DEBUG:
+                    debug(format, argA, argB);
+                    break;
+                case INFO:
+                    info(format, argA, argB);
+                    break;
+                case WARN:
+                    warn(format, argA, argB);
+                    break;
+                case ERROR:
+                    error(format, argA, argB);
+                    break;
+            }
+        }
+
+        @Override
+        public void log(InternalLogLevel level, String format, Object... arguments) {
+            if (level == null) {
+                return;
+            }
+            switch (level) {
+                case TRACE:
+                    trace(format, arguments);
+                    break;
+                case DEBUG:
+                    debug(format, arguments);
+                    break;
+                case INFO:
+                    info(format, arguments);
+                    break;
+                case WARN:
+                    warn(format, arguments);
+                    break;
+                case ERROR:
+                    error(format, arguments);
+                    break;
+            }
+        }
+
+        @Override
+        public void log(InternalLogLevel level, String msg, Throwable t) {
+            if (level == null) {
+                return;
+            }
+            switch (level) {
+                case TRACE:
+                    trace(msg, t);
+                    break;
+                case DEBUG:
+                    debug(msg, t);
+                    break;
+                case INFO:
+                    info(msg, t);
+                    break;
+                case WARN:
+                    warn(msg, t);
+                    break;
+                case ERROR:
+                    error(msg, t);
+                    break;
+            }
+        }
+    }
+}

+ 72 - 413
lts-core/src/main/java/com/lts/remoting/netty/NettyRemotingClient.java

@@ -2,88 +2,53 @@ package com.lts.remoting.netty;
 
 import com.lts.core.logger.Logger;
 import com.lts.core.logger.LoggerFactory;
-import com.lts.remoting.ChannelEventListener;
-import com.lts.remoting.InvokeCallback;
-import com.lts.remoting.RemotingClient;
-import com.lts.remoting.common.Pair;
+import com.lts.remoting.*;
+import com.lts.remoting.Channel;
 import com.lts.remoting.common.RemotingHelper;
-import com.lts.remoting.common.RemotingUtil;
-import com.lts.remoting.exception.RemotingConnectException;
-import com.lts.remoting.exception.RemotingSendRequestException;
-import com.lts.remoting.exception.RemotingTimeoutException;
-import com.lts.remoting.exception.RemotingTooMuchRequestException;
+import com.lts.remoting.exception.RemotingException;
 import com.lts.remoting.protocol.RemotingCommand;
 import io.netty.bootstrap.Bootstrap;
 import io.netty.channel.*;
+import io.netty.channel.ChannelFuture;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.channel.socket.nio.NioSocketChannel;
-import io.netty.handler.timeout.IdleState;
 import io.netty.handler.timeout.IdleStateEvent;
 import io.netty.handler.timeout.IdleStateHandler;
 import io.netty.util.concurrent.DefaultEventExecutorGroup;
 
 import java.net.SocketAddress;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.*;
+import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
 
 /**
- * Remoting客户端实现
+ * @author Robert HG (254963746@qq.com) on 11/3/15.
  */
-public class NettyRemotingClient extends NettyRemotingAbstract implements RemotingClient {
-    private static final Logger log = LoggerFactory.getLogger(RemotingHelper.RemotingLogName);
-
-    private static final long LockTimeoutMillis = 3000;
+public class NettyRemotingClient extends AbstractRemotingClient {
+    private static final Logger LOGGER = LoggerFactory.getLogger(RemotingHelper.RemotingLogName);
 
-    private final NettyClientConfig nettyClientConfig;
     private final Bootstrap bootstrap = new Bootstrap();
     private final EventLoopGroup eventLoopGroup;
-    private final Lock lockChannelTables = new ReentrantLock();
-    private final ConcurrentHashMap<String /* addr */, ChannelWrapper> channelTables = new ConcurrentHashMap<String, ChannelWrapper>();
-    // 定时器
-    private final Timer timer = new Timer("ClientHouseKeepingService", true);
-    // 处理Callback应答器
-    private final ExecutorService publicExecutor;
-    private final ChannelEventListener channelEventListener;
     private DefaultEventExecutorGroup defaultEventExecutorGroup;
 
-    public NettyRemotingClient(final NettyClientConfig nettyClientConfig) {
-        this(nettyClientConfig, null);
+    public NettyRemotingClient(final RemotingClientConfig remotingClientConfig) {
+        this(remotingClientConfig, null);
     }
 
-    public NettyRemotingClient(final NettyClientConfig nettyClientConfig,
+    public NettyRemotingClient(final RemotingClientConfig remotingClientConfig,
                                final ChannelEventListener channelEventListener) {
-        super(nettyClientConfig.getClientOnewaySemaphoreValue(), nettyClientConfig
-                .getClientAsyncSemaphoreValue());
-        this.nettyClientConfig = nettyClientConfig;
-        this.channelEventListener = channelEventListener;
-
-        int publicThreadNums = nettyClientConfig.getClientCallbackExecutorThreads();
-        if (publicThreadNums <= 0) {
-            publicThreadNums = 4;
-        }
-
-        this.publicExecutor = Executors.newFixedThreadPool(publicThreadNums, new ThreadFactory() {
-            private AtomicInteger threadIndex = new AtomicInteger(0);
-
-            @Override
-            public Thread newThread(Runnable r) {
-                return new Thread(r, "NettyClientPublicExecutor_" + this.threadIndex.incrementAndGet());
-            }
-        });
+        super(remotingClientConfig, channelEventListener);
 
-        this.eventLoopGroup = new NioEventLoopGroup(nettyClientConfig.getClientSelectorThreads());
+        this.eventLoopGroup = new NioEventLoopGroup(remotingClientConfig.getClientSelectorThreads());
     }
 
     @Override
-    public void start() {
+    protected void clientStart() throws RemotingException {
+
+        NettyLogger.setNettyLoggerFactory();
+
         this.defaultEventExecutorGroup = new DefaultEventExecutorGroup(//
-                nettyClientConfig.getClientWorkerThreads(), //
+                remotingClientConfig.getClientWorkerThreads(), //
                 new ThreadFactory() {
 
                     private AtomicInteger threadIndex = new AtomicInteger(0);
@@ -95,360 +60,45 @@ public class NettyRemotingClient extends NettyRemotingAbstract implements Remoti
                     }
                 });
 
+        final NettyCodecFactory nettyCodecFactory = new NettyCodecFactory(getCodec());
+
         this.bootstrap.group(this.eventLoopGroup).channel(NioSocketChannel.class)
                 .option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer<SocketChannel>() {
             @Override
             public void initChannel(SocketChannel ch) throws Exception {
                 ch.pipeline().addLast(//
                         defaultEventExecutorGroup, //
-                        new NettyEncoder(), //
-                        new NettyDecoder(), //
-                        new IdleStateHandler(nettyClientConfig.getReaderIdleTimeSeconds(), nettyClientConfig.getWriterIdleTimeSeconds(), nettyClientConfig.getClientChannelMaxIdleTimeSeconds()),//
+                        nettyCodecFactory.getEncoder(), //
+                        nettyCodecFactory.getDecoder(), //
+                        new IdleStateHandler(remotingClientConfig.getReaderIdleTimeSeconds(), remotingClientConfig.getWriterIdleTimeSeconds(), remotingClientConfig.getClientChannelMaxIdleTimeSeconds()),//
                         new NettyConnectManageHandler(), //
                         new NettyClientHandler());
             }
         });
 
-        // 每隔1秒扫描下异步调用超时情况
-        this.timer.scheduleAtFixedRate(new TimerTask() {
-
-            @Override
-            public void run() {
-                try {
-                    NettyRemotingClient.this.scanResponseTable();
-                } catch (Exception e) {
-                    log.error("scanResponseTable exception", e);
-                }
-            }
-        }, 1000 * 3, 1000);
-
-        if (this.channelEventListener != null) {
-            this.nettyEventExecutor.start();
-        }
     }
 
     @Override
-    public void shutdown() {
-        try {
-            this.timer.cancel();
-
-            for (ChannelWrapper cw : this.channelTables.values()) {
-                this.closeChannel(null, cw.getChannel());
-            }
+    protected void clientShutdown() {
 
-            this.channelTables.clear();
+        this.eventLoopGroup.shutdownGracefully();
 
-            this.eventLoopGroup.shutdownGracefully();
-
-            if (this.nettyEventExecutor != null) {
-                this.nettyEventExecutor.shutdown();
-            }
-
-            if (this.defaultEventExecutorGroup != null) {
-                this.defaultEventExecutorGroup.shutdownGracefully();
-            }
-        } catch (Exception e) {
-            log.error("NettyRemotingClient shutdown exception, ", e);
-        }
-
-        if (this.publicExecutor != null) {
-            try {
-                this.publicExecutor.shutdown();
-            } catch (Exception e) {
-                log.error("NettyRemotingServer shutdown exception, ", e);
-            }
+        if (this.defaultEventExecutorGroup != null) {
+            this.defaultEventExecutorGroup.shutdownGracefully();
         }
     }
 
-    private Channel getAndCreateChannel(final String addr) throws InterruptedException {
-
-        ChannelWrapper cw = this.channelTables.get(addr);
-        if (cw != null && cw.isOK()) {
-            return cw.getChannel();
-        }
-
-        return this.createChannel(addr);
-    }
-
-    private Channel createChannel(final String addr) throws InterruptedException {
-        ChannelWrapper cw = this.channelTables.get(addr);
-        if (cw != null && cw.isOK()) {
-            return cw.getChannel();
-        }
-
-        // 进入临界区后,不能有阻塞操作,网络连接采用异步方式
-        if (this.lockChannelTables.tryLock(LockTimeoutMillis, TimeUnit.MILLISECONDS)) {
-            try {
-                boolean createNewConnection = false;
-                cw = this.channelTables.get(addr);
-                if (cw != null) {
-                    // channel正常
-                    if (cw.isOK()) {
-                        return cw.getChannel();
-                    }
-                    // 正在连接,退出锁等待
-                    else if (!cw.getChannelFuture().isDone()) {
-                        createNewConnection = false;
-                    }
-                    // 说明连接不成功
-                    else {
-                        this.channelTables.remove(addr);
-                        createNewConnection = true;
-                    }
-                }
-                // ChannelWrapper不存在
-                else {
-                    createNewConnection = true;
-                }
-
-                if (createNewConnection) {
-                    ChannelFuture channelFuture =
-                            this.bootstrap.connect(RemotingHelper.string2SocketAddress(addr));
-                    log.info("createChannel: begin to connect remote host[{}] asynchronously", addr);
-                    cw = new ChannelWrapper(channelFuture);
-                    this.channelTables.put(addr, cw);
-                }
-            } catch (Exception e) {
-                log.error("createChannel: create channel exception", e);
-            } finally {
-                this.lockChannelTables.unlock();
-            }
-        } else {
-            log.warn("createChannel: try to lock channel table, but timeout, {}ms", LockTimeoutMillis);
-        }
-
-        if (cw != null) {
-            ChannelFuture channelFuture = cw.getChannelFuture();
-            if (channelFuture.awaitUninterruptibly(this.nettyClientConfig.getConnectTimeoutMillis())) {
-                if (cw.isOK()) {
-                    log.info("createChannel: connect remote host[{}] success, {}", addr,
-                            channelFuture.toString());
-                    return cw.getChannel();
-                } else {
-                    log.warn(
-                            "createChannel: connect remote host[" + addr + "] failed, "
-                                    + channelFuture.toString(), channelFuture.cause());
-                }
-            } else {
-                log.warn("createChannel: connect remote host[{}] timeout {}ms, {}", addr,
-                        this.nettyClientConfig.getConnectTimeoutMillis(), channelFuture.toString());
-            }
-        }
-
-        return null;
-    }
-
-    public void closeChannel(final String addr, final Channel channel) {
-        if (null == channel)
-            return;
-
-        final String addrRemote = null == addr ? RemotingHelper.parseChannelRemoteAddr(channel) : addr;
-
-        try {
-            if (this.lockChannelTables.tryLock(LockTimeoutMillis, TimeUnit.MILLISECONDS)) {
-                try {
-                    boolean removeItemFromTable = true;
-                    final ChannelWrapper prevCW = this.channelTables.get(addrRemote);
-
-                    log.info("closeChannel: begin close the channel[{}] Found: {}", addrRemote,
-                            (prevCW != null));
-
-                    if (null == prevCW) {
-                        log.info(
-                                "closeChannel: the channel[{}] has been removed from the channel table before",
-                                addrRemote);
-                        removeItemFromTable = false;
-                    } else if (prevCW.getChannel() != channel) {
-                        log.info(
-                                "closeChannel: the channel[{}] has been closed before, and has been created again, nothing to do.",
-                                addrRemote);
-                        removeItemFromTable = false;
-                    }
-
-                    if (removeItemFromTable) {
-                        this.channelTables.remove(addrRemote);
-                        log.info("closeChannel: the channel[{}] was removed from channel table", addrRemote);
-                    }
-
-                    RemotingUtil.closeChannel(channel);
-                } catch (Exception e) {
-                    log.error("closeChannel: close the channel exception", e);
-                } finally {
-                    this.lockChannelTables.unlock();
-                }
-            } else {
-                log.warn("closeChannel: try to lock channel table, but timeout, {}ms", LockTimeoutMillis);
-            }
-        } catch (InterruptedException e) {
-            log.error("closeChannel exception", e);
-        }
-    }
-
-    public void closeChannel(final Channel channel) {
-        if (null == channel)
-            return;
-
-        try {
-            if (this.lockChannelTables.tryLock(LockTimeoutMillis, TimeUnit.MILLISECONDS)) {
-                try {
-                    boolean removeItemFromTable = true;
-                    ChannelWrapper prevCW = null;
-                    String addrRemote = null;
-
-                    for (String key : channelTables.keySet()) {
-                        ChannelWrapper prev = this.channelTables.get(key);
-                        if (prev.getChannel() != null) {
-                            if (prev.getChannel() == channel) {
-                                prevCW = prev;
-                                addrRemote = key;
-                                break;
-                            }
-                        }
-                    }
-
-                    if (null == prevCW) {
-                        log.info(
-                                "eventCloseChannel: the channel[{}] has been removed from the channel table before",
-                                addrRemote);
-                        removeItemFromTable = false;
-                    }
-
-                    if (removeItemFromTable) {
-                        this.channelTables.remove(addrRemote);
-                        log.info("closeChannel: the channel[{}] was removed from channel table", addrRemote);
-                        RemotingUtil.closeChannel(channel);
-                    }
-                } catch (Exception e) {
-                    log.error("closeChannel: close the channel exception", e);
-                } finally {
-                    this.lockChannelTables.unlock();
-                }
-            } else {
-                log.warn("closeChannel: try to lock channel table, but timeout, {}ms", LockTimeoutMillis);
-            }
-        } catch (InterruptedException e) {
-            log.error("closeChannel exception", e);
-        }
-    }
-
-    @Override
-    public void registerProcessor(int requestCode, NettyRequestProcessor processor, ExecutorService executor) {
-        ExecutorService executorThis = executor;
-        if (null == executor) {
-            executorThis = this.publicExecutor;
-        }
-
-        Pair<NettyRequestProcessor, ExecutorService> pair =
-                new Pair<NettyRequestProcessor, ExecutorService>(processor, executorThis);
-        this.processorTable.put(requestCode, pair);
-    }
-
-    @Override
-    public void registerDefaultProcessor(NettyRequestProcessor processor, ExecutorService executor) {
-        this.defaultRequestProcessor = new Pair<NettyRequestProcessor, ExecutorService>(processor, executor);
-    }
-
-    @Override
-    public RemotingCommand invokeSync(String addr, final RemotingCommand request, long timeoutMillis)
-            throws InterruptedException, RemotingConnectException, RemotingSendRequestException,
-            RemotingTimeoutException {
-        final Channel channel = this.getAndCreateChannel(addr);
-        if (channel != null && channel.isActive()) {
-            try {
-                return this.invokeSyncImpl(channel, request, timeoutMillis);
-            } catch (RemotingSendRequestException e) {
-                log.warn("invokeSync: send request exception, so close the channel[{}]", addr);
-                this.closeChannel(addr, channel);
-                throw e;
-            } catch (RemotingTimeoutException e) {
-                log.warn("invokeSync: wait response timeout exception, the channel[{}]", addr);
-                // 超时异常如果关闭连接可能会产生连锁反应
-                // this.closeChannel(addr, channel);
-                throw e;
-            }
-        } else {
-            this.closeChannel(addr, channel);
-            throw new RemotingConnectException(addr);
-        }
-    }
-
-    @Override
-    public void invokeAsync(String addr, RemotingCommand request, long timeoutMillis,
-                            InvokeCallback invokeCallback) throws InterruptedException, RemotingConnectException,
-            RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException {
-        final Channel channel = this.getAndCreateChannel(addr);
-        if (channel != null && channel.isActive()) {
-            try {
-                this.invokeAsyncImpl(channel, request, timeoutMillis, invokeCallback);
-            } catch (RemotingSendRequestException e) {
-                log.warn("invokeAsync: send request exception, so close the channel[{}]", addr);
-                this.closeChannel(addr, channel);
-                throw e;
-            }
-        } else {
-            this.closeChannel(addr, channel);
-            throw new RemotingConnectException(addr);
-        }
-    }
-
-    @Override
-    public void invokeOneway(String addr, RemotingCommand request, long timeoutMillis)
-            throws InterruptedException, RemotingConnectException, RemotingTooMuchRequestException,
-            RemotingTimeoutException, RemotingSendRequestException {
-        final Channel channel = this.getAndCreateChannel(addr);
-        if (channel != null && channel.isActive()) {
-            try {
-                this.invokeOnewayImpl(channel, request, timeoutMillis);
-            } catch (RemotingSendRequestException e) {
-                log.warn("invokeOneway: send request exception, so close the channel[{}]", addr);
-                this.closeChannel(addr, channel);
-                throw e;
-            }
-        } else {
-            this.closeChannel(addr, channel);
-            throw new RemotingConnectException(addr);
-        }
-    }
-
-    @Override
-    public ExecutorService getCallbackExecutor() {
-        return this.publicExecutor;
-    }
-
     @Override
-    public ChannelEventListener getChannelEventListener() {
-        return channelEventListener;
-    }
-
-    private class ChannelWrapper {
-        private final ChannelFuture channelFuture;
-
-
-        public ChannelWrapper(ChannelFuture channelFuture) {
-            this.channelFuture = channelFuture;
-        }
-
-
-        public boolean isOK() {
-            return (this.channelFuture.channel() != null && this.channelFuture.channel().isActive());
-        }
-
-
-        private Channel getChannel() {
-            return this.channelFuture.channel();
-        }
-
-
-        public ChannelFuture getChannelFuture() {
-            return channelFuture;
-        }
+    protected com.lts.remoting.ChannelFuture connect(SocketAddress socketAddress) {
+        ChannelFuture channelFuture = this.bootstrap.connect(socketAddress);
+        return new com.lts.remoting.netty.NettyChannelFuture(channelFuture);
     }
 
     class NettyClientHandler extends SimpleChannelInboundHandler<RemotingCommand> {
 
         @Override
         protected void channelRead0(ChannelHandlerContext ctx, RemotingCommand msg) throws Exception {
-            processMessageReceived(ctx, msg);
+            processMessageReceived(new NettyChannel(ctx), msg);
         }
     }
 
@@ -458,52 +108,57 @@ public class NettyRemotingClient extends NettyRemotingAbstract implements Remoti
                             SocketAddress localAddress, ChannelPromise promise) throws Exception {
             final String local = localAddress == null ? "UNKNOW" : localAddress.toString();
             final String remote = remoteAddress == null ? "UNKNOW" : remoteAddress.toString();
-            log.info("NETTY CLIENT PIPELINE: CONNECT  {} => {}", local, remote);
+            LOGGER.info("CLIENT : CONNECT  {} => {}", local, remote);
             super.connect(ctx, remoteAddress, localAddress, promise);
 
-            if (NettyRemotingClient.this.channelEventListener != null) {
-                NettyRemotingClient.this.putNettyEvent(new NettyEvent(NettyEventType.CONNECT, remoteAddress
-                        .toString(), ctx.channel()));
+            if (channelEventListener != null) {
+                assert remoteAddress != null;
+                putRemotingEvent(new RemotingEvent(RemotingEventType.CONNECT, remoteAddress
+                        .toString(), new NettyChannel(ctx)));
             }
         }
 
         @Override
         public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
-            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel());
-            log.info("NETTY CLIENT PIPELINE: DISCONNECT {}", remoteAddress);
-            closeChannel(ctx.channel());
+
+            Channel channel = new NettyChannel(ctx);
+
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
+            LOGGER.info("CLIENT : DISCONNECT {}", remoteAddress);
+            closeChannel(channel);
             super.disconnect(ctx, promise);
 
-            if (NettyRemotingClient.this.channelEventListener != null) {
-                NettyRemotingClient.this.putNettyEvent(new NettyEvent(NettyEventType.CLOSE, remoteAddress
-                        .toString(), ctx.channel()));
+            if (channelEventListener != null) {
+                putRemotingEvent(new RemotingEvent(RemotingEventType.CLOSE, remoteAddress, channel));
             }
         }
 
 
         @Override
         public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
-            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel());
-            log.info("NETTY CLIENT PIPELINE: CLOSE {}", remoteAddress);
-            closeChannel(ctx.channel());
+            Channel channel = new NettyChannel(ctx);
+
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
+            LOGGER.info("CLIENT : CLOSE {}", remoteAddress);
+            closeChannel(channel);
             super.close(ctx, promise);
 
-            if (NettyRemotingClient.this.channelEventListener != null) {
-                NettyRemotingClient.this.putNettyEvent(new NettyEvent(NettyEventType.CLOSE, remoteAddress
-                        .toString(), ctx.channel()));
+            if (channelEventListener != null) {
+                putRemotingEvent(new RemotingEvent(RemotingEventType.CLOSE, remoteAddress, channel));
             }
         }
 
-
         @Override
         public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
-            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel());
-            log.warn("NETTY CLIENT PIPELINE: exceptionCaught {}", remoteAddress);
-            log.warn("NETTY CLIENT PIPELINE: exceptionCaught exception.", cause);
-            closeChannel(ctx.channel());
-            if (NettyRemotingClient.this.channelEventListener != null) {
-                NettyRemotingClient.this.putNettyEvent(new NettyEvent(NettyEventType.EXCEPTION, remoteAddress
-                        .toString(), ctx.channel()));
+
+            Channel channel = new NettyChannel(ctx);
+
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
+            LOGGER.warn("CLIENT : exceptionCaught {}", remoteAddress);
+            LOGGER.warn("CLIENT : exceptionCaught exception.", cause);
+            closeChannel(channel);
+            if (channelEventListener != null) {
+                putRemotingEvent(new RemotingEvent(RemotingEventType.EXCEPTION, remoteAddress, channel));
             }
         }
 
@@ -512,21 +167,25 @@ public class NettyRemotingClient extends NettyRemotingAbstract implements Remoti
             if (evt instanceof IdleStateEvent) {
                 IdleStateEvent event = (IdleStateEvent) evt;
 
-                final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel());
+                Channel channel = new NettyChannel(ctx);
 
-                if (event.state().equals(IdleState.ALL_IDLE)) {
-                    log.warn("NETTY CLIENT PIPELINE: IDLE [{}]", remoteAddress);
-                    closeChannel(ctx.channel());
+                final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
+
+                if (event.state().equals(io.netty.handler.timeout.IdleState.ALL_IDLE)) {
+                    LOGGER.warn("CLIENT : IDLE [{}]", remoteAddress);
+                    closeChannel(channel);
                 }
 
-                if (NettyRemotingClient.this.channelEventListener != null) {
-                    NettyEventType nettyEventType = NettyEventType.valueOf(event.state().name());
-                    NettyRemotingClient.this.putNettyEvent(new NettyEvent(nettyEventType,
-                            remoteAddress.toString(), ctx.channel()));
+                if (channelEventListener != null) {
+                    RemotingEventType remotingEventType = RemotingEventType.valueOf(event.state().name());
+                    putRemotingEvent(new RemotingEvent(remotingEventType,
+                            remoteAddress, channel));
                 }
             }
 
             ctx.fireUserEventTriggered(evt);
         }
     }
+
+
 }

+ 67 - 180
lts-core/src/main/java/com/lts/remoting/netty/NettyRemotingServer.java

@@ -1,16 +1,9 @@
 package com.lts.remoting.netty;
 
 import com.lts.core.logger.Logger;
-import com.lts.core.logger.LoggerFactory;
-import com.lts.remoting.ChannelEventListener;
-import com.lts.remoting.InvokeCallback;
-import com.lts.remoting.RemotingServer;
-import com.lts.remoting.common.Pair;
+import com.lts.remoting.*;
 import com.lts.remoting.common.RemotingHelper;
-import com.lts.remoting.common.RemotingUtil;
-import com.lts.remoting.exception.RemotingSendRequestException;
-import com.lts.remoting.exception.RemotingTimeoutException;
-import com.lts.remoting.exception.RemotingTooMuchRequestException;
+import com.lts.remoting.exception.RemotingException;
 import com.lts.remoting.protocol.RemotingCommand;
 import io.netty.bootstrap.ServerBootstrap;
 import io.netty.channel.*;
@@ -23,266 +16,156 @@ import io.netty.handler.timeout.IdleStateHandler;
 import io.netty.util.concurrent.DefaultEventExecutorGroup;
 
 import java.net.InetSocketAddress;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicInteger;
 
-
 /**
- * Remoting服务端实现
+ * @author Robert HG (254963746@qq.com) on 11/3/15.
  */
-public class NettyRemotingServer extends NettyRemotingAbstract implements RemotingServer {
-    private static final Logger log = LoggerFactory.getLogger(RemotingHelper.RemotingLogName);
+public class NettyRemotingServer extends AbstractRemotingServer {
+
+    public static final Logger LOGGER = AbstractRemotingServer.LOGGER;
+
     private final ServerBootstrap serverBootstrap;
     private final EventLoopGroup eventLoopGroup;
-    private final NettyServerConfig nettyServerConfig;
-    // 处理Callback应答器
-    private final ExecutorService publicExecutor;
-    private final ChannelEventListener channelEventListener;
-    // 定时器
-    private final Timer timer = new Timer("ServerHouseKeepingService", true);
     private DefaultEventExecutorGroup defaultEventExecutorGroup;
 
-
-    public NettyRemotingServer(final NettyServerConfig nettyServerConfig) {
-        this(nettyServerConfig, null);
+    public NettyRemotingServer(RemotingServerConfig remotingServerConfig) {
+        this(remotingServerConfig, null);
     }
 
-
-    public NettyRemotingServer(final NettyServerConfig nettyServerConfig,
-                               final ChannelEventListener channelEventListener) {
-        super(nettyServerConfig.getServerOnewaySemaphoreValue(), nettyServerConfig
-                .getServerAsyncSemaphoreValue());
+    public NettyRemotingServer(RemotingServerConfig remotingServerConfig, final ChannelEventListener channelEventListener) {
+        super(remotingServerConfig, channelEventListener);
         this.serverBootstrap = new ServerBootstrap();
-        this.nettyServerConfig = nettyServerConfig;
-        this.channelEventListener = channelEventListener;
-
-        int publicThreadNums = nettyServerConfig.getServerCallbackExecutorThreads();
-        if (publicThreadNums <= 0) {
-            publicThreadNums = 4;
-        }
-
-        this.publicExecutor = Executors.newFixedThreadPool(publicThreadNums, new ThreadFactory() {
-            private AtomicInteger threadIndex = new AtomicInteger(0);
-
-
-            @Override
-            public Thread newThread(Runnable r) {
-                return new Thread(r, "NettyServerPublicExecutor_" + this.threadIndex.incrementAndGet());
-            }
-        });
-
-        this.eventLoopGroup = new NioEventLoopGroup(nettyServerConfig.getServerSelectorThreads());
+        this.eventLoopGroup = new NioEventLoopGroup(remotingServerConfig.getServerSelectorThreads());
     }
 
-
     @Override
-    public void start() throws InterruptedException {
+    protected void serverStart() throws RemotingException {
+
+        NettyLogger.setNettyLoggerFactory();
+
         this.defaultEventExecutorGroup = new DefaultEventExecutorGroup(//
-                nettyServerConfig.getServerWorkerThreads(), //
+                remotingServerConfig.getServerWorkerThreads(), //
                 new ThreadFactory() {
 
                     private AtomicInteger threadIndex = new AtomicInteger(0);
 
-
                     @Override
                     public Thread newThread(Runnable r) {
                         return new Thread(r, "NettyServerWorkerThread_" + this.threadIndex.incrementAndGet());
                     }
                 });
 
+        final NettyCodecFactory nettyCodecFactory = new NettyCodecFactory(getCodec());
+
         this.serverBootstrap.group(this.eventLoopGroup, new NioEventLoopGroup())
                 .channel(NioServerSocketChannel.class)
                 .option(ChannelOption.SO_BACKLOG, 65536)
                 .option(ChannelOption.SO_REUSEADDR, true)
                         //
                 .childOption(ChannelOption.TCP_NODELAY, true)
-                .localAddress(new InetSocketAddress(this.nettyServerConfig.getListenPort()))
+                .localAddress(new InetSocketAddress(this.remotingServerConfig.getListenPort()))
                 .childHandler(new ChannelInitializer<SocketChannel>() {
                     @Override
                     public void initChannel(SocketChannel ch) throws Exception {
                         ch.pipeline().addLast(
                                 //
                                 defaultEventExecutorGroup, //
-                                new NettyEncoder(), //
-                                new NettyDecoder(), //
-                                new IdleStateHandler(nettyServerConfig.getReaderIdleTimeSeconds(),
-                                        nettyServerConfig.getWriterIdleTimeSeconds(), nettyServerConfig.getServerChannelMaxIdleTimeSeconds()),//
+                                nettyCodecFactory.getEncoder(), //
+                                nettyCodecFactory.getDecoder(), //
+                                new IdleStateHandler(remotingServerConfig.getReaderIdleTimeSeconds(),
+                                        remotingServerConfig.getWriterIdleTimeSeconds(), remotingServerConfig.getServerChannelMaxIdleTimeSeconds()),//
                                 new NettyConnectManageHandler(), //
                                 new NettyServerHandler());
                     }
                 });
 
-        this.serverBootstrap.bind().sync();
-
-        if (this.channelEventListener != null) {
-            this.nettyEventExecutor.start();
-        }
-
-        // 每隔1秒扫描下异步调用超时情况
-        this.timer.scheduleAtFixedRate(new TimerTask() {
-
-            @Override
-            public void run() {
-                try {
-                    NettyRemotingServer.this.scanResponseTable();
-                } catch (Exception e) {
-                    log.error("scanResponseTable exception", e);
-                }
-            }
-        }, 1000 * 3, 1000);
-    }
-
-
-    @Override
-    public void registerProcessor(int requestCode, NettyRequestProcessor processor, ExecutorService executor) {
-        ExecutorService executorThis = executor;
-        if (null == executor) {
-            executorThis = this.publicExecutor;
-        }
-
-        Pair<NettyRequestProcessor, ExecutorService> pair =
-                new Pair<NettyRequestProcessor, ExecutorService>(processor, executorThis);
-        this.processorTable.put(requestCode, pair);
-    }
-
-
-    @Override
-    public void registerDefaultProcessor(NettyRequestProcessor processor, ExecutorService executor) {
-        this.defaultRequestProcessor = new Pair<NettyRequestProcessor, ExecutorService>(processor, executor);
-    }
-
-
-    @Override
-    public RemotingCommand invokeSync(final Channel channel, final RemotingCommand request,
-                                      final long timeoutMillis) throws InterruptedException, RemotingSendRequestException,
-            RemotingTimeoutException {
-        return this.invokeSyncImpl(channel, request, timeoutMillis);
-    }
-
-
-    @Override
-    public void invokeAsync(Channel channel, RemotingCommand request, long timeoutMillis,
-                            InvokeCallback invokeCallback) throws InterruptedException, RemotingTooMuchRequestException,
-            RemotingTimeoutException, RemotingSendRequestException {
-        this.invokeAsyncImpl(channel, request, timeoutMillis, invokeCallback);
-    }
 
-
-    @Override
-    public void invokeOneway(Channel channel, RemotingCommand request, long timeoutMillis)
-            throws InterruptedException, RemotingTooMuchRequestException, RemotingTimeoutException,
-            RemotingSendRequestException {
-        this.invokeOnewayImpl(channel, request, timeoutMillis);
-    }
-
-
-    @Override
-    public void shutdown() {
         try {
-            if (this.timer != null) {
-                this.timer.cancel();
-            }
-
-            this.eventLoopGroup.shutdownGracefully();
-
-            if (this.nettyEventExecutor != null) {
-                this.nettyEventExecutor.shutdown();
-            }
-
-            if (this.defaultEventExecutorGroup != null) {
-                this.defaultEventExecutorGroup.shutdownGracefully();
-            }
-        } catch (Exception e) {
-            log.error("NettyRemotingServer shutdown exception, ", e);
-        }
-
-        if (this.publicExecutor != null) {
-            try {
-                this.publicExecutor.shutdown();
-            } catch (Exception e) {
-                log.error("NettyRemotingServer shutdown exception, ", e);
-            }
+            this.serverBootstrap.bind().sync();
+        } catch (InterruptedException e) {
+            throw new RemotingException("Start Netty server bootstrap error", e);
         }
     }
 
     @Override
-    public ChannelEventListener getChannelEventListener() {
-        return channelEventListener;
-    }
+    protected void serverShutdown() {
 
+        this.eventLoopGroup.shutdownGracefully();
 
-    @Override
-    public ExecutorService getCallbackExecutor() {
-        return this.publicExecutor;
+        if (this.defaultEventExecutorGroup != null) {
+            this.defaultEventExecutorGroup.shutdownGracefully();
+        }
     }
 
     class NettyServerHandler extends SimpleChannelInboundHandler<RemotingCommand> {
 
         @Override
         protected void channelRead0(ChannelHandlerContext ctx, RemotingCommand msg) throws Exception {
-            processMessageReceived(ctx, msg);
+            processMessageReceived(new NettyChannel(ctx), msg);
         }
     }
 
     class NettyConnectManageHandler extends ChannelDuplexHandler {
         @Override
         public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
-            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel());
-            log.info("NETTY SERVER PIPELINE: channelRegistered {}", remoteAddress);
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(new NettyChannel(ctx));
+            LOGGER.info("SERVER : channelRegistered {}", remoteAddress);
             super.channelRegistered(ctx);
         }
 
 
         @Override
         public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
-            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel());
-            log.info("NETTY SERVER PIPELINE: channelUnregistered, the channel[{}]", remoteAddress);
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(new NettyChannel(ctx));
+            LOGGER.info("SERVER : channelUnregistered, the channel[{}]", remoteAddress);
             super.channelUnregistered(ctx);
         }
 
         @Override
         public void channelActive(ChannelHandlerContext ctx) throws Exception {
-            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel());
-            log.info("NETTY SERVER PIPELINE: channelActive, the channel[{}]", remoteAddress);
+            com.lts.remoting.Channel channel = new NettyChannel(ctx);
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
+            LOGGER.info("SERVER: channelActive, the channel[{}]", remoteAddress);
             super.channelActive(ctx);
 
-            if (NettyRemotingServer.this.channelEventListener != null) {
-                NettyRemotingServer.this.putNettyEvent(new NettyEvent(NettyEventType.CONNECT, remoteAddress, ctx.channel()));
+            if (channelEventListener != null) {
+                putRemotingEvent(new RemotingEvent(RemotingEventType.CONNECT, remoteAddress, channel));
             }
         }
 
         @Override
         public void channelInactive(ChannelHandlerContext ctx) throws Exception {
-            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel());
-            log.info("NETTY SERVER PIPELINE: channelInactive, the channel[{}]", remoteAddress);
+            com.lts.remoting.Channel channel = new NettyChannel(ctx);
+
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
+            LOGGER.info("SERVER: channelInactive, the channel[{}]", remoteAddress);
             super.channelInactive(ctx);
 
-            if (NettyRemotingServer.this.channelEventListener != null) {
-                NettyRemotingServer.this.putNettyEvent(new NettyEvent(NettyEventType.CLOSE, remoteAddress, ctx.channel()));
+            if (channelEventListener != null) {
+                putRemotingEvent(new RemotingEvent(RemotingEventType.CLOSE, remoteAddress, channel));
             }
         }
 
-
         @Override
         public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
             if (evt instanceof IdleStateEvent) {
                 IdleStateEvent event = (IdleStateEvent) evt;
 
-                final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel());
+                com.lts.remoting.Channel channel = new NettyChannel(ctx);
+
+                final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
 
                 if (event.state().equals(IdleState.ALL_IDLE)) {
-                    log.warn("NETTY SERVER PIPELINE: IDLE [{}]", remoteAddress);
-                    RemotingUtil.closeChannel(ctx.channel());
+                    LOGGER.warn("SERVER: IDLE [{}]", remoteAddress);
+                    RemotingHelper.closeChannel(channel);
                 }
 
-                if (NettyRemotingServer.this.channelEventListener != null) {
-                    NettyEventType nettyEventType = NettyEventType.valueOf(event.state().name());
-                    NettyRemotingServer.this.putNettyEvent(new NettyEvent(nettyEventType,
-                            remoteAddress, ctx.channel()));
+                if (channelEventListener != null) {
+                    RemotingEventType remotingEventType = RemotingEventType.valueOf(event.state().name());
+                    putRemotingEvent(new RemotingEvent(remotingEventType,
+                            remoteAddress, channel));
                 }
             }
 
@@ -292,15 +175,19 @@ public class NettyRemotingServer extends NettyRemotingAbstract implements Remoti
 
         @Override
         public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
-            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel());
-            log.warn("NETTY SERVER PIPELINE: exceptionCaught {}", remoteAddress);
-            log.warn("NETTY SERVER PIPELINE: exceptionCaught exception.", cause);
 
-            if (NettyRemotingServer.this.channelEventListener != null) {
-                NettyRemotingServer.this.putNettyEvent(new NettyEvent(NettyEventType.EXCEPTION, remoteAddress, ctx.channel()));
+            com.lts.remoting.Channel channel = new NettyChannel(ctx);
+
+            final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(channel);
+            LOGGER.warn("SERVER: exceptionCaught {}", remoteAddress);
+            LOGGER.warn("SERVER: exceptionCaught exception.", cause);
+
+            if (channelEventListener != null) {
+                putRemotingEvent(new RemotingEvent(RemotingEventType.EXCEPTION, remoteAddress, channel));
             }
 
-            RemotingUtil.closeChannel(ctx.channel());
+            RemotingHelper.closeChannel(channel);
         }
     }
+
 }

+ 5 - 150
lts-core/src/main/java/com/lts/remoting/protocol/RemotingCommand.java

@@ -2,36 +2,16 @@ package com.lts.remoting.protocol;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.annotation.JSONField;
-import com.lts.core.logger.Logger;
-import com.lts.core.logger.LoggerFactory;
 import com.lts.remoting.CommandBody;
-import com.lts.remoting.exception.RemotingCommandException;
 
-import java.nio.ByteBuffer;
 import java.util.concurrent.atomic.AtomicInteger;
 
-
 /**
  * @author Robert HG (254963746@qq.com)
- *
- * Remoting模块中,服务器与客户端通过传递RemotingCommand来交互
- * <p/>
- * // Remoting通信协议
- * //
- * // 协议格式 <length> <header length> <header data> <body length> <body data> <body class>
- * //            1        2               3             4             5             6
- * // 协议分4部分,含义分别如下
- * //     1、大端4个字节整数,等于2、3、4、5、6长度总和
- * //     2、header 信息长度 大端4个字节整数,等于3的长度
- * //     3、header 信息内容
- * //     4、body 信息长度  大端4个字节整数,等于5的长度
- * //     5、body 信息内容
- * //     6、body 的class名称
+ *  Remoting模块中,服务器与客户端通过传递RemotingCommand来交互
  */
 public class RemotingCommand {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(RemotingCommand.class);
-
     private static final int RPC_TYPE = 0; // 0, REQUEST_COMMAND
     private static final int RPC_ONEWAY = 1; // 1, RPC
     // 1, Oneway
@@ -50,7 +30,7 @@ public class RemotingCommand {
      */
     private transient CommandBody body;
 
-    protected RemotingCommand() {
+    private RemotingCommand() {
     }
 
     public static RemotingCommand createRequestCommand(int code, CommandBody body) {
@@ -81,127 +61,14 @@ public class RemotingCommand {
         return createResponseCommand(code, null, body);
     }
 
-    public static RemotingCommand decode(final byte[] array) {
-        ByteBuffer byteBuffer = ByteBuffer.wrap(array);
-        return decode(byteBuffer);
+    public void setBody(CommandBody body) {
+        this.body = body;
     }
 
-    public static RemotingCommand decode(final ByteBuffer byteBuffer) {
-        int length = byteBuffer.limit();
-        int headerLength = byteBuffer.getInt();
-        byte[] headerData = new byte[headerLength];
-        byteBuffer.get(headerData);
-
-        RemotingCommand cmd = RemotingSerializable.decode(headerData, RemotingCommand.class);
-
-        if (length - 4 - headerLength > 0) {
-            int bodyLength = byteBuffer.getInt();
-            int bodyClassLength = length - 4 - headerLength - 4 - bodyLength;
-
-            if (bodyLength > 0) {
-
-                byte[] bodyData = new byte[bodyLength];
-                byteBuffer.get(bodyData);
-
-                byte[] bodyClassData = new byte[bodyClassLength];
-                byteBuffer.get(bodyClassData);
-
-                CommandBody body = null;
-                try {
-                    body = (CommandBody) RemotingSerializable.decode(bodyData, Class.forName(new String(bodyClassData)));
-                } catch (ClassNotFoundException e) {
-                    LOGGER.error(e.getMessage(), e);
-                }
-                cmd.body = body;
-            }
-        }
-
-        return cmd;
-    }
-
-    public <T> T getBody() {
+    public <T extends CommandBody> T getBody() {
         return (T) body;
     }
 
-//    /**
-//     * 检查commandBody
-//     *
-//     * @return
-//     */
-//    public boolean checkCommandBody() throws RemotingCommandFieldCheckException {
-//        if (body != null) {
-//            body.checkFields();
-//
-//            try {
-//                Field[] fields = ReflectionUtils.findFields(body.getClass());
-//                for (Field field : fields) {
-//                    if (!Modifier.isStatic(field.getModifiers())) {
-//
-//                        Annotation annotation = field.getAnnotation(NotNull.class);
-//
-//                        field.setAccessible(true);
-//                        Object value = field.get(body);
-//
-//                        if (annotation != null && value == null) {
-//                            throw new RemotingCommandFieldCheckException("the field <" + field.getName() + "> is null");
-//                        }
-//                    }
-//                }
-//            } catch (IllegalAccessException e) {
-//                throw new RemotingCommandFieldCheckException("check field error !", e);
-//            }
-//        }
-//
-//        return true;
-//    }
-
-    public ByteBuffer encode() throws RemotingCommandException {
-
-        // 1> header length size
-        int length = 4;
-
-        // 2> header data length
-        byte[] headerData = RemotingSerializable.encode(this);
-        length += headerData.length;
-
-        byte[] bodyData = null;
-        byte[] bodyClass = null;
-        if (body != null) {
-            // body data
-            bodyData = RemotingSerializable.encode(body);
-            length += bodyData.length;
-
-            bodyClass = body.getClass().getName().getBytes();
-            length += bodyClass.length;
-
-            length += 4;
-        }
-
-        ByteBuffer result = ByteBuffer.allocate(4 + length);
-
-        // length
-        result.putInt(length);
-
-        // header length
-        result.putInt(headerData.length);
-
-        // header data
-        result.put(headerData);
-
-        if (bodyData != null) {
-            //  body length
-            result.putInt(bodyData.length);
-            //  body data
-            result.put(bodyData);
-            // body class
-            result.put(bodyClass);
-        }
-
-        result.flip();
-
-        return result;
-    }
-
     public void markResponseType() {
         int bits = 1 << RPC_TYPE;
         this.flag |= bits;
@@ -213,36 +80,30 @@ public class RemotingCommand {
         return (this.flag & bits) == bits;
     }
 
-
     public void markOnewayRPC() {
         int bits = 1 << RPC_ONEWAY;
         this.flag |= bits;
     }
 
-
     @JSONField(serialize = false)
     public boolean isOnewayRPC() {
         int bits = 1 << RPC_ONEWAY;
         return (this.flag & bits) == bits;
     }
 
-
     public int getCode() {
         return code;
     }
 
-
     public void setCode(int code) {
         this.code = code;
     }
 
-
     @JSONField(serialize = false)
     public RemotingCommandType getType() {
         if (this.isResponseType()) {
             return RemotingCommandType.RESPONSE_COMMAND;
         }
-
         return RemotingCommandType.REQUEST_COMMAND;
     }
 
@@ -250,22 +111,18 @@ public class RemotingCommand {
         return version;
     }
 
-
     public void setVersion(int version) {
         this.version = version;
     }
 
-
     public int getOpaque() {
         return opaque;
     }
 
-
     public void setOpaque(int opaque) {
         this.opaque = opaque;
     }
 
-
     public int getFlag() {
         return flag;
     }
@@ -282,12 +139,10 @@ public class RemotingCommand {
         this.flag = flag;
     }
 
-
     public String getRemark() {
         return remark;
     }
 
-
     public void setRemark(String remark) {
         this.remark = remark;
     }

+ 2 - 12
lts-core/src/main/java/com/lts/remoting/protocol/RemotingSerializable.java

@@ -4,11 +4,11 @@ import com.alibaba.fastjson.JSON;
 
 import java.nio.charset.Charset;
 
-
 /**
  * 复杂对象的序列化,利用json来实现
  */
 public abstract class RemotingSerializable {
+
     public static String toJson(final Object obj, boolean prettyFormat) {
         return JSON.toJSONString(obj, prettyFormat);
     }
@@ -19,10 +19,7 @@ public abstract class RemotingSerializable {
 
     public static byte[] encode(final Object obj) {
         final String json = toJson(obj, false);
-        if (json != null) {
-            return json.getBytes(Charset.forName("UTF-8"));
-        }
-        return null;
+        return json.getBytes(Charset.forName("UTF-8"));
     }
 
     public static <T> T decode(final byte[] data, Class<T> classOfT) {
@@ -38,11 +35,4 @@ public abstract class RemotingSerializable {
         return toJson(this, prettyFormat);
     }
 
-    public byte[] encode() {
-        final String json = this.toJson();
-        if (json != null) {
-            return json.getBytes();
-        }
-        return null;
-    }
 }

+ 0 - 12
lts-core/src/main/java/com/lts/remoting/protocol/protocol.txt

@@ -1,12 +0,0 @@
-
-// Remoting通信协议
-//
-// 协议格式 <length> <header length> <header data> <body length> <body data> <body class>
-//            1        2               3             4             5             6
-// 协议分4部分,含义分别如下
-//     1、大端4个字节整数,等于2、3、4、5、6长度总和
-//     2、header 信息长度 大端4个字节整数,等于3的长度
-//     3、header 信息内容
-//     4、body 信息长度  大端4个字节整数,等于5的长度
-//     5、body 信息内容
-//     6、body 的class名称

+ 0 - 4
lts-core/src/main/java/com/lts/remoting/util/ReflectionUtils.java

@@ -11,10 +11,6 @@ public class ReflectionUtils {
 
     /**
      * 得到所有field , 包括 父类
-     *
-     * @param clazz
-     * @return
-     * @throws IllegalAccessException
      */
     public static Field[] findFields(Class clazz) throws IllegalAccessException {
         final List<Field> fieldList = new ArrayList<Field>();

+ 0 - 115
lts-core/src/test/java/com/lts/remoting/JsonTest.java

@@ -1,115 +0,0 @@
-package com.lts.remoting;
-
-import com.alibaba.fastjson.JSON;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Robert HG (254963746@qq.com) on 8/14/14.
- */
-public class JsonTest {
-
-    public static void main(String[] args) {
-
-        Job job = new Job();
-        job.setJ(11);
-        Map<String, Object> map = new HashMap<String, Object>();
-        map.put("key", 1111);
-        map.put("key2", "ddd");
-        map.put("key3", new JobInfo());
-
-        job.setMap(map);
-
-        List<JobInfo> list = new ArrayList<JobInfo>();
-
-        JobInfo jobInfo = new JobInfo();
-        jobInfo.setI(11111);
-        map.put("hahah", true);
-        jobInfo.setMap(map);
-
-        list.add(jobInfo);
-
-        job.setJobList(list);
-
-        String json = JSON.toJSONString(job);
-        System.out.println(json);
-
-        Job job1 = JSON.parseObject(json, Job.class);
-
-        System.out.println(job1);
-    }
-
-    private static class JobInfo {
-
-        private int i;
-        private Map<String, Object> map;
-
-        public int getI() {
-            return i;
-        }
-
-        public void setI(int i) {
-            this.i = i;
-        }
-
-        public Map<String, Object> getMap() {
-            return map;
-        }
-
-        public void setMap(Map<String, Object> map) {
-            this.map = map;
-        }
-
-        @Override
-        public String toString() {
-            return "JobInfo{" +
-                    "i=" + i +
-                    ", map=" + map +
-                    '}';
-        }
-    }
-
-    private static class Job {
-        private int j;
-        private List<JobInfo> jobList;
-
-        private Map<String, Object> map;
-
-        public int getJ() {
-            return j;
-        }
-
-        public List<JobInfo> getJobList() {
-            return jobList;
-        }
-
-        public void setJobList(List<JobInfo> jobList) {
-            this.jobList = jobList;
-        }
-
-        public void setJ(int j) {
-            this.j = j;
-        }
-
-
-        public Map<String, Object> getMap() {
-            return map;
-        }
-
-        public void setMap(Map<String, Object> map) {
-            this.map = map;
-        }
-
-        @Override
-        public String toString() {
-            return "Job{" +
-                    "j=" + j +
-                    ", jobList=" + jobList +
-                    ", map=" + map +
-                    '}';
-        }
-    }
-}

+ 0 - 229
lts-core/src/test/java/com/lts/remoting/NettyRPCTest.java

@@ -1,229 +0,0 @@
-package com.lts.remoting;
-
-
-import com.lts.core.logger.Logger;
-import com.lts.core.logger.LoggerFactory;
-import com.lts.remoting.annotation.Nullable;
-import com.lts.remoting.exception.*;
-import com.lts.remoting.netty.*;
-import com.lts.remoting.protocol.RemotingCommand;
-import io.netty.channel.ChannelHandlerContext;
-import org.junit.Test;
-
-import java.util.concurrent.Executors;
-
-import static org.junit.Assert.assertTrue;
-
-/**
- * @author Robert HG (254963746@qq.com) on 7/21/14.
- */
-public class NettyRPCTest {
-
-    private static final Logger logger = LoggerFactory.getLogger(NettyRPCTest.class);
-
-    public static RemotingClient createRemotingClient() {
-        NettyClientConfig config = new NettyClientConfig();
-        RemotingClient client = new NettyRemotingClient(config);
-        client.start();
-        return client;
-    }
-
-
-    public static RemotingServer createRemotingServer() throws InterruptedException {
-        NettyServerConfig config = new NettyServerConfig();
-        RemotingServer remotingServer = new NettyRemotingServer(config);
-        remotingServer.registerProcessor(0, new NettyRequestProcessor() {
-            private int i = 0;
-
-
-            @Override
-            public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) {
-                System.out.println("processRequest=" + request + " " + (i++));
-                request.setRemark("hello, I am respponse " + ctx.channel().remoteAddress());
-                return request;
-            }
-        }, Executors.newCachedThreadPool());
-        remotingServer.start();
-        return remotingServer;
-    }
-
-
-    @Test
-    public void test_RPC_Sync() throws InterruptedException, RemotingConnectException,
-            RemotingSendRequestException, RemotingTimeoutException {
-        RemotingServer server = createRemotingServer();
-        RemotingClient client = createRemotingClient();
-
-        for (int i = 0; i < 100; i++) {
-            TestRequestHeader requestHeader = new TestRequestHeader();
-            requestHeader.setCount(i);
-            requestHeader.setMessageTitle("HelloMessageTitle");
-            RemotingCommand request = RemotingCommand.createRequestCommand(0, requestHeader);
-            RemotingCommand response = client.invokeSync("127.0.0.1:8888", request, 1000 * 3000);
-            System.out.println("invoke result = " + response);
-            assertTrue(response != null);
-        }
-
-        client.shutdown();
-        server.shutdown();
-        System.out.println("-----------------------------------------------------------------");
-    }
-
-
-    @Test
-    public void test_RPC_Oneway() throws InterruptedException, RemotingConnectException,
-            RemotingTimeoutException, RemotingTooMuchRequestException, RemotingSendRequestException {
-        RemotingServer server = createRemotingServer();
-        RemotingClient client = createRemotingClient();
-
-        for (int i = 0; i < 100; i++) {
-            RemotingCommand request = RemotingCommand.createRequestCommand(0, null);
-            request.setRemark(String.valueOf(i));
-            client.invokeOneway("127.0.0.1:8888", request, 1000 * 3);
-        }
-
-        client.shutdown();
-        server.shutdown();
-        System.out.println("-----------------------------------------------------------------");
-    }
-
-
-    @Test
-    public void test_RPC_Async() throws InterruptedException, RemotingConnectException,
-            RemotingTimeoutException, RemotingTooMuchRequestException, RemotingSendRequestException {
-        RemotingServer server = createRemotingServer();
-        RemotingClient client = createRemotingClient();
-
-        for (int i = 0; i < 100; i++) {
-            RemotingCommand request = RemotingCommand.createRequestCommand(0, null);
-            request.setRemark(String.valueOf(i));
-            client.invokeAsync("127.0.0.1:8888", request, 1000 * 3, new InvokeCallback() {
-                @Override
-                public void operationComplete(ResponseFuture responseFuture) {
-                    System.out.println(responseFuture.getResponseCommand());
-                }
-            });
-        }
-
-        Thread.sleep(1000 * 3);
-
-        client.shutdown();
-        server.shutdown();
-        System.out.println("-----------------------------------------------------------------");
-    }
-
-
-    @Test
-    public void test_server_call_client() throws InterruptedException, RemotingConnectException,
-            RemotingSendRequestException, RemotingTimeoutException {
-        final RemotingServer server = createRemotingServer();
-        final RemotingClient client = createRemotingClient();
-
-        server.registerProcessor(0, new NettyRequestProcessor() {
-            @Override
-            public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) {
-                try {
-                    return server.invokeSync(ctx.channel(), request, 1000 * 10);
-                } catch (InterruptedException e) {
-                    logger.error(e.getMessage(), e);
-                } catch (RemotingSendRequestException e) {
-                    logger.error(e.getMessage(), e);
-                } catch (RemotingTimeoutException e) {
-                    logger.error(e.getMessage(), e);
-                }
-
-                return null;
-            }
-        }, Executors.newCachedThreadPool());
-
-        client.registerProcessor(0, new NettyRequestProcessor() {
-            @Override
-            public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) {
-                System.out.println("client receive server request = " + request);
-                request.setRemark("client remark");
-                return request;
-            }
-        }, Executors.newCachedThreadPool());
-
-        for (int i = 0; i < 3; i++) {
-            RemotingCommand request = RemotingCommand.createRequestCommand(0, null);
-            RemotingCommand response = client.invokeSync("127.0.0.1:8888", request, 1000 * 3);
-            System.out.println("invoke result = " + response);
-            assertTrue(response != null);
-        }
-
-        client.shutdown();
-        server.shutdown();
-        System.out.println("-----------------------------------------------------------------");
-    }
-
-}
-
-
-class TestRequestHeader implements CommandBody {
-    @Nullable
-    private Integer count;
-
-    @Nullable
-    private String messageTitle;
-
-
-    public Integer getCount() {
-        return count;
-    }
-
-
-    public void setCount(Integer count) {
-        this.count = count;
-    }
-
-
-    public String getMessageTitle() {
-        return messageTitle;
-    }
-
-
-    public void setMessageTitle(String messageTitle) {
-        this.messageTitle = messageTitle;
-    }
-
-    @Override
-    public void checkFields() throws RemotingCommandFieldCheckException {
-
-    }
-}
-
-
-class TestResponseHeader implements CommandBody {
-    @Nullable
-    private Integer count;
-
-    @Nullable
-    private String messageTitle;
-
-
-    public Integer getCount() {
-        return count;
-    }
-
-
-    public void setCount(Integer count) {
-        this.count = count;
-    }
-
-
-    public String getMessageTitle() {
-        return messageTitle;
-    }
-
-
-    public void setMessageTitle(String messageTitle) {
-        this.messageTitle = messageTitle;
-    }
-
-    @Override
-    public void checkFields() throws RemotingCommandFieldCheckException {
-
-    }
-}
-

+ 1 - 1
lts-example/src/main/java/com/lts/example/api/JobTrackerTest.java

@@ -75,7 +75,7 @@ public class JobTrackerTest {
         jobTracker.addConfig("jdbc.url", "jdbc:mysql://127.0.0.1:3306/lts");
         jobTracker.addConfig("jdbc.username", "root");
         jobTracker.addConfig("jdbc.password", "root");
-
+        // jobTracker.addConfig("lts.remoting", "mina");
         // 延迟批量刷盘业务日志开关
 //        jobTracker.addConfig("lazy.job.logger", "true");
 

+ 1 - 0
lts-example/src/main/java/com/lts/example/api/TaskTrackerTest.java

@@ -30,6 +30,7 @@ public class TaskTrackerTest {
         // 可选址  leveldb(默认), rocksdb, berkeleydb
         // taskTracker.addConfig("job.fail.store", "leveldb");
         taskTracker.addConfig("lts.monitor.url", "http://localhost:8081/");
+        // taskTracker.addConfig("lts.remoting", "mina");
         taskTracker.start();
 
         Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {

+ 5 - 5
lts-jobclient/src/main/java/com/lts/jobclient/JobClient.java

@@ -25,9 +25,9 @@ import com.lts.jobclient.support.JobFinishedHandler;
 import com.lts.jobclient.support.JobSubmitExecutor;
 import com.lts.jobclient.support.JobSubmitProtector;
 import com.lts.jobclient.support.SubmitCallback;
-import com.lts.remoting.InvokeCallback;
-import com.lts.remoting.netty.NettyRequestProcessor;
-import com.lts.remoting.netty.ResponseFuture;
+import com.lts.remoting.AsyncCallback;
+import com.lts.remoting.RemotingProcessor;
+import com.lts.remoting.ResponseFuture;
 import com.lts.remoting.protocol.RemotingCommand;
 
 import java.util.Collections;
@@ -155,7 +155,7 @@ public class JobClient<T extends JobClientNode, App extends Application> extends
     private void asyncSubmit(RemotingCommand requestCommand, final SubmitCallback submitCallback)
             throws JobTrackerNotFoundException {
         final CountDownLatch latch = new CountDownLatch(1);
-        remotingClient.invokeAsync(requestCommand, new InvokeCallback() {
+        remotingClient.invokeAsync(requestCommand, new AsyncCallback() {
             @Override
             public void operationComplete(ResponseFuture responseFuture) {
                 try {
@@ -199,7 +199,7 @@ public class JobClient<T extends JobClientNode, App extends Application> extends
     }
 
     @Override
-    protected NettyRequestProcessor getDefaultProcessor() {
+    protected RemotingProcessor getDefaultProcessor() {
         return new RemotingDispatcher(jobFinishedHandler);
     }
 

+ 2 - 2
lts-jobclient/src/main/java/com/lts/jobclient/processor/AbstractProcessor.java

@@ -1,10 +1,10 @@
 package com.lts.jobclient.processor;
 
-import com.lts.remoting.netty.NettyRequestProcessor;
+import com.lts.remoting.RemotingProcessor;
 
 /**
  * @author Robert HG (254963746@qq.com) on 8/16/14.
  */
-public abstract class AbstractProcessor implements NettyRequestProcessor{
+public abstract class AbstractProcessor implements RemotingProcessor {
 
 }

+ 2 - 2
lts-jobclient/src/main/java/com/lts/jobclient/processor/JobFinishedProcessor.java

@@ -5,9 +5,9 @@ import com.lts.core.logger.LoggerFactory;
 import com.lts.core.protocol.JobProtos;
 import com.lts.core.protocol.command.JobFinishedRequest;
 import com.lts.jobclient.support.JobFinishedHandler;
+import com.lts.remoting.Channel;
 import com.lts.remoting.exception.RemotingCommandException;
 import com.lts.remoting.protocol.RemotingCommand;
-import io.netty.channel.ChannelHandlerContext;
 
 /**
  * @author Robert HG (254963746@qq.com) on 8/18/14.
@@ -23,7 +23,7 @@ public class JobFinishedProcessor extends AbstractProcessor {
     }
 
     @Override
-    public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request)
+    public RemotingCommand processRequest(Channel Channel, RemotingCommand request)
             throws RemotingCommandException {
 
         JobFinishedRequest requestBody = request.getBody();

+ 6 - 6
lts-jobclient/src/main/java/com/lts/jobclient/processor/RemotingDispatcher.java

@@ -2,11 +2,11 @@ package com.lts.jobclient.processor;
 
 import com.lts.core.protocol.JobProtos;
 import com.lts.jobclient.support.JobFinishedHandler;
+import com.lts.remoting.Channel;
 import com.lts.remoting.exception.RemotingCommandException;
-import com.lts.remoting.netty.NettyRequestProcessor;
+import com.lts.remoting.RemotingProcessor;
 import com.lts.remoting.protocol.RemotingCommand;
 import com.lts.remoting.protocol.RemotingProtos;
-import io.netty.channel.ChannelHandlerContext;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -20,19 +20,19 @@ import static com.lts.core.protocol.JobProtos.RequestCode.valueOf;
  */
 public class RemotingDispatcher extends AbstractProcessor {
 
-    private final Map<JobProtos.RequestCode, NettyRequestProcessor> processors = new HashMap<JobProtos.RequestCode, NettyRequestProcessor>();
+    private final Map<JobProtos.RequestCode, RemotingProcessor> processors = new HashMap<JobProtos.RequestCode, RemotingProcessor>();
 
     public RemotingDispatcher(JobFinishedHandler jobFinishedHandler) {
         processors.put(JOB_FINISHED, new JobFinishedProcessor(jobFinishedHandler));
     }
 
     @Override
-    public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) throws RemotingCommandException {
+    public RemotingCommand processRequest(Channel channel, RemotingCommand request) throws RemotingCommandException {
         JobProtos.RequestCode code = valueOf(request.getCode());
-        NettyRequestProcessor processor = processors.get(code);
+        RemotingProcessor processor = processors.get(code);
         if (processor == null) {
             return RemotingCommand.createResponseCommand(RemotingProtos.ResponseCode.REQUEST_CODE_NOT_SUPPORTED.code(), "request code not supported!");
         }
-        return processor.processRequest(ctx, request);
+        return processor.processRequest(channel, request);
     }
 }

+ 2 - 2
lts-jobtracker/src/main/java/com/lts/jobtracker/JobTracker.java

@@ -19,7 +19,7 @@ import com.lts.jobtracker.support.cluster.TaskTrackerManager;
 import com.lts.jobtracker.support.listener.JobNodeChangeListener;
 import com.lts.jobtracker.support.listener.JobTrackerMasterChangeListener;
 import com.lts.queue.*;
-import com.lts.remoting.netty.NettyRequestProcessor;
+import com.lts.remoting.RemotingProcessor;
 
 /**
  * @author Robert HG (254963746@qq.com) on 7/23/14.
@@ -106,7 +106,7 @@ public class JobTracker extends AbstractServerNode<JobTrackerNode, JobTrackerApp
     }
 
     @Override
-    protected NettyRequestProcessor getDefaultProcessor() {
+    protected RemotingProcessor getDefaultProcessor() {
         return new RemotingDispatcher(application);
     }
 

+ 2 - 3
lts-jobtracker/src/main/java/com/lts/jobtracker/channel/ChannelWrapper.java

@@ -1,7 +1,7 @@
 package com.lts.jobtracker.channel;
 
 import com.lts.core.cluster.NodeType;
-import io.netty.channel.Channel;
+import com.lts.remoting.Channel;
 
 /**
  * @author Robert HG (254963746@qq.com) on 7/24/14.
@@ -59,10 +59,9 @@ public class ChannelWrapper {
     }
 
     public boolean isClosed() {
-        return !channel.isOpen();
+        return channel.isClosed();
     }
 
-
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;

+ 3 - 3
lts-jobtracker/src/main/java/com/lts/jobtracker/processor/AbstractProcessor.java → lts-jobtracker/src/main/java/com/lts/jobtracker/processor/AbstractRemotingProcessor.java

@@ -1,16 +1,16 @@
 package com.lts.jobtracker.processor;
 
 import com.lts.jobtracker.domain.JobTrackerApplication;
-import com.lts.remoting.netty.NettyRequestProcessor;
+import com.lts.remoting.RemotingProcessor;
 
 /**
  * @author Robert HG (254963746@qq.com) on 8/16/14.
  */
-public abstract class AbstractProcessor implements NettyRequestProcessor{
+public abstract class AbstractRemotingProcessor implements RemotingProcessor {
 
     protected JobTrackerApplication application;
 
-    public AbstractProcessor(JobTrackerApplication application) {
+    public AbstractRemotingProcessor(JobTrackerApplication application) {
         this.application = application;
     }
 

+ 3 - 3
lts-jobtracker/src/main/java/com/lts/jobtracker/processor/JobBizLogProcessor.java

@@ -8,23 +8,23 @@ import com.lts.core.protocol.JobProtos;
 import com.lts.core.protocol.command.BizLogSendRequest;
 import com.lts.core.support.SystemClock;
 import com.lts.jobtracker.domain.JobTrackerApplication;
+import com.lts.remoting.Channel;
 import com.lts.remoting.exception.RemotingCommandException;
 import com.lts.remoting.protocol.RemotingCommand;
-import io.netty.channel.ChannelHandlerContext;
 
 import java.util.List;
 
 /**
  * @author Robert HG (254963746@qq.com) on 3/30/15.
  */
-public class JobBizLogProcessor extends AbstractProcessor {
+public class JobBizLogProcessor extends AbstractRemotingProcessor {
 
     public JobBizLogProcessor(JobTrackerApplication application) {
         super(application);
     }
 
     @Override
-    public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) throws RemotingCommandException {
+    public RemotingCommand processRequest(Channel channel, RemotingCommand request) throws RemotingCommandException {
 
         BizLogSendRequest requestBody = request.getBody();
 

+ 6 - 5
lts-jobtracker/src/main/java/com/lts/jobtracker/processor/JobFinishedProcessor.java

@@ -4,6 +4,7 @@ import com.lts.biz.logger.domain.JobLogPo;
 import com.lts.biz.logger.domain.LogType;
 import com.lts.core.commons.utils.CollectionUtils;
 import com.lts.core.commons.utils.DateUtils;
+import com.lts.core.commons.utils.JSONUtils;
 import com.lts.core.constant.Constants;
 import com.lts.core.constant.Level;
 import com.lts.core.domain.Action;
@@ -25,10 +26,10 @@ import com.lts.jobtracker.support.JobDomainConverter;
 import com.lts.queue.domain.JobFeedbackPo;
 import com.lts.queue.domain.JobPo;
 import com.lts.queue.exception.DuplicateJobException;
+import com.lts.remoting.Channel;
 import com.lts.remoting.exception.RemotingCommandException;
 import com.lts.remoting.protocol.RemotingCommand;
 import com.lts.remoting.protocol.RemotingProtos;
-import io.netty.channel.ChannelHandlerContext;
 
 import java.util.ArrayList;
 import java.util.Date;
@@ -38,7 +39,7 @@ import java.util.List;
  * @author Robert HG (254963746@qq.com) on 8/17/14.
  *         TaskTracker 完成任务 的处理器
  */
-public class JobFinishedProcessor extends AbstractProcessor {
+public class JobFinishedProcessor extends AbstractRemotingProcessor {
 
     private ClientNotifier clientNotifier;
     private JobTrackerMonitor monitor;
@@ -79,7 +80,7 @@ public class JobFinishedProcessor extends AbstractProcessor {
     }
 
     @Override
-    public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request)
+    public RemotingCommand processRequest(Channel channel, RemotingCommand request)
             throws RemotingCommandException {
 
         TtJobFinishedRequest requestBody = request.getBody();
@@ -277,7 +278,7 @@ public class JobFinishedProcessor extends AbstractProcessor {
         try {
             application.getExecutingJobQueue().add(jobPo);
         } catch (DuplicateJobException e) {
-            LOGGER.warn(e.getMessage(), e);
+            LOGGER.warn("Add Executing Job error, jobPo={}", JSONUtils.toJSONString(jobPo), e);
             application.getExecutableJobQueue().resume(jobPo);
             return null;
         }
@@ -382,7 +383,7 @@ public class JobFinishedProcessor extends AbstractProcessor {
             try {
                 application.getExecutableJobQueue().add(jobPo);
             } catch (DuplicateJobException e) {
-                LOGGER.error(e.getMessage(), e);
+                LOGGER.warn("Add Executable Job error jobPo={}", JSONUtils.toJSONString(jobPo), e);
             }
             // 从正在执行的队列中移除
             application.getExecutingJobQueue().remove(jobPo.getJobId());

+ 3 - 3
lts-jobtracker/src/main/java/com/lts/jobtracker/processor/JobPullProcessor.java

@@ -6,15 +6,15 @@ import com.lts.core.protocol.JobProtos;
 import com.lts.core.protocol.command.JobPullRequest;
 import com.lts.jobtracker.domain.JobTrackerApplication;
 import com.lts.jobtracker.support.JobPusher;
+import com.lts.remoting.Channel;
 import com.lts.remoting.exception.RemotingCommandException;
 import com.lts.remoting.protocol.RemotingCommand;
-import io.netty.channel.ChannelHandlerContext;
 
 /**
  * @author Robert HG (254963746@qq.com) on 7/24/14.
  *         处理 TaskTracker的 Job pull 请求
  */
-public class JobPullProcessor extends AbstractProcessor {
+public class JobPullProcessor extends AbstractRemotingProcessor {
 
     private JobPusher jobPusher;
 
@@ -27,7 +27,7 @@ public class JobPullProcessor extends AbstractProcessor {
     }
 
     @Override
-    public RemotingCommand processRequest(final ChannelHandlerContext ctx, final RemotingCommand request) throws RemotingCommandException {
+    public RemotingCommand processRequest(final Channel ctx, final RemotingCommand request) throws RemotingCommandException {
 
         JobPullRequest requestBody = request.getBody();
 

+ 3 - 3
lts-jobtracker/src/main/java/com/lts/jobtracker/processor/JobSubmitProcessor.java

@@ -7,15 +7,15 @@ import com.lts.core.protocol.JobProtos;
 import com.lts.core.protocol.command.JobSubmitRequest;
 import com.lts.core.protocol.command.JobSubmitResponse;
 import com.lts.jobtracker.domain.JobTrackerApplication;
+import com.lts.remoting.Channel;
 import com.lts.remoting.exception.RemotingCommandException;
 import com.lts.remoting.protocol.RemotingCommand;
-import io.netty.channel.ChannelHandlerContext;
 
 /**
  * @author Robert HG (254963746@qq.com) on 7/24/14.
  *         客户端提交任务的处理器
  */
-public class JobSubmitProcessor extends AbstractProcessor {
+public class JobSubmitProcessor extends AbstractRemotingProcessor {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(JobSubmitProcessor.class);
 
@@ -24,7 +24,7 @@ public class JobSubmitProcessor extends AbstractProcessor {
     }
 
     @Override
-    public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) throws RemotingCommandException {
+    public RemotingCommand processRequest(Channel channel, RemotingCommand request) throws RemotingCommandException {
 
         JobSubmitRequest jobSubmitRequest = request.getBody();
 

+ 11 - 12
lts-jobtracker/src/main/java/com/lts/jobtracker/processor/RemotingDispatcher.java

@@ -3,14 +3,13 @@ package com.lts.jobtracker.processor;
 import com.lts.core.cluster.NodeType;
 import com.lts.core.protocol.JobProtos;
 import com.lts.core.protocol.command.AbstractCommandBody;
-import com.lts.core.remoting.RemotingServerDelegate;
 import com.lts.jobtracker.channel.ChannelWrapper;
 import com.lts.jobtracker.domain.JobTrackerApplication;
+import com.lts.remoting.Channel;
+import com.lts.remoting.RemotingProcessor;
 import com.lts.remoting.exception.RemotingCommandException;
-import com.lts.remoting.netty.NettyRequestProcessor;
 import com.lts.remoting.protocol.RemotingCommand;
 import com.lts.remoting.protocol.RemotingProtos;
-import io.netty.channel.ChannelHandlerContext;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -21,9 +20,9 @@ import static com.lts.core.protocol.JobProtos.RequestCode;
  * @author Robert HG (254963746@qq.com) on 7/23/14.
  *         job tracker 总的处理器, 每一种命令对应不同的处理器
  */
-public class RemotingDispatcher extends AbstractProcessor {
+public class RemotingDispatcher extends AbstractRemotingProcessor {
 
-    private final Map<RequestCode, NettyRequestProcessor> processors = new HashMap<RequestCode, NettyRequestProcessor>();
+    private final Map<RequestCode, RemotingProcessor> processors = new HashMap<RequestCode, RemotingProcessor>();
 
     public RemotingDispatcher(JobTrackerApplication application) {
         super(application);
@@ -34,35 +33,35 @@ public class RemotingDispatcher extends AbstractProcessor {
     }
 
     @Override
-    public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) throws RemotingCommandException {
+    public RemotingCommand processRequest(Channel channel, RemotingCommand request) throws RemotingCommandException {
         // 心跳
         if (request.getCode() == JobProtos.RequestCode.HEART_BEAT.code()) {
-            commonHandler(ctx, request);
+            commonHandler(channel, request);
             return RemotingCommand.createResponseCommand(JobProtos.ResponseCode.HEART_BEAT_SUCCESS.code(), "");
         }
 
         // 其他的请求code
         RequestCode code = RequestCode.valueOf(request.getCode());
-        NettyRequestProcessor processor = processors.get(code);
+        RemotingProcessor processor = processors.get(code);
         if (processor == null) {
             return RemotingCommand.createResponseCommand(RemotingProtos.ResponseCode.REQUEST_CODE_NOT_SUPPORTED.code(), "request code not supported!");
         }
-        commonHandler(ctx, request);
-        return processor.processRequest(ctx, request);
+        commonHandler(channel, request);
+        return processor.processRequest(channel, request);
     }
 
     /**
      * 1. 将 channel 纳入管理中(不存在就加入)
      * 2. 更新 TaskTracker 节点信息(可用线程数)
      */
-    private void commonHandler(ChannelHandlerContext ctx, RemotingCommand request) {
+    private void commonHandler(Channel channel, RemotingCommand request) {
         AbstractCommandBody commandBody = request.getBody();
         String nodeGroup = commandBody.getNodeGroup();
         String identity = commandBody.getIdentity();
         NodeType nodeType = NodeType.valueOf(commandBody.getNodeType());
 
         // 1. 将 channel 纳入管理中(不存在就加入)
-        application.getChannelManager().offerChannel(new ChannelWrapper(ctx.channel(), nodeType, nodeGroup, identity));
+        application.getChannelManager().offerChannel(new ChannelWrapper(channel, nodeType, nodeGroup, identity));
     }
 
 }

+ 3 - 3
lts-jobtracker/src/main/java/com/lts/jobtracker/support/ClientNotifier.java

@@ -15,8 +15,8 @@ import com.lts.core.protocol.command.JobFinishedRequest;
 import com.lts.core.remoting.RemotingServerDelegate;
 import com.lts.jobtracker.domain.JobClientNode;
 import com.lts.jobtracker.domain.JobTrackerApplication;
-import com.lts.remoting.InvokeCallback;
-import com.lts.remoting.netty.ResponseFuture;
+import com.lts.remoting.AsyncCallback;
+import com.lts.remoting.ResponseFuture;
 import com.lts.remoting.protocol.RemotingCommand;
 
 import java.util.*;
@@ -110,7 +110,7 @@ public class ClientNotifier {
         final Holder<Boolean> result = new Holder<Boolean>();
         try {
             final CountDownLatch latch = new CountDownLatch(1);
-            getRemotingServer().invokeAsync(jobClientNode.getChannel().getChannel(), commandRequest, new InvokeCallback() {
+            getRemotingServer().invokeAsync(jobClientNode.getChannel().getChannel(), commandRequest, new AsyncCallback() {
                 @Override
                 public void operationComplete(ResponseFuture responseFuture) {
                     try {

+ 6 - 5
lts-jobtracker/src/main/java/com/lts/jobtracker/support/JobPusher.java

@@ -3,6 +3,7 @@ package com.lts.jobtracker.support;
 import com.lts.biz.logger.domain.JobLogPo;
 import com.lts.biz.logger.domain.LogType;
 import com.lts.core.commons.utils.Holder;
+import com.lts.core.commons.utils.JSONUtils;
 import com.lts.core.constant.Constants;
 import com.lts.core.constant.Level;
 import com.lts.core.exception.RemotingSendException;
@@ -20,8 +21,8 @@ import com.lts.jobtracker.domain.TaskTrackerNode;
 import com.lts.jobtracker.monitor.JobTrackerMonitor;
 import com.lts.queue.domain.JobPo;
 import com.lts.queue.exception.DuplicateJobException;
-import com.lts.remoting.InvokeCallback;
-import com.lts.remoting.netty.ResponseFuture;
+import com.lts.remoting.AsyncCallback;
+import com.lts.remoting.ResponseFuture;
 import com.lts.remoting.protocol.RemotingCommand;
 
 import java.util.concurrent.CountDownLatch;
@@ -134,7 +135,7 @@ public class JobPusher {
         try {
             application.getExecutingJobQueue().add(jobPo);
         } catch (DuplicateJobException e) {
-            LOGGER.warn(e.getMessage(), e);
+            LOGGER.warn("Add Executing Job error, jobPo={}", JSONUtils.toJSONString(jobPo), e);
             application.getExecutableJobQueue().resume(jobPo);
             return PushResult.FAILED;
         }
@@ -150,7 +151,7 @@ public class JobPusher {
 
         final CountDownLatch latch = new CountDownLatch(1);
         try {
-            remotingServer.invokeAsync(taskTrackerNode.getChannel().getChannel(), commandRequest, new InvokeCallback() {
+            remotingServer.invokeAsync(taskTrackerNode.getChannel().getChannel(), commandRequest, new AsyncCallback() {
                 @Override
                 public void operationComplete(ResponseFuture responseFuture) {
                     try {
@@ -192,7 +193,7 @@ public class JobPusher {
                 jobPo.setIsRunning(true);
                 application.getExecutableJobQueue().add(jobPo);
             } catch (DuplicateJobException e) {
-                LOGGER.warn(e.getMessage(), e);
+                LOGGER.warn("Add Executable Job error jobPo={}", JSONUtils.toJSONString(jobPo), e);
                 needResume = false;
             }
             application.getExecutingJobQueue().remove(jobPo.getJobId());

+ 5 - 5
lts-jobtracker/src/main/java/com/lts/jobtracker/support/checker/ExecutingDeadJobChecker.java

@@ -21,11 +21,11 @@ import com.lts.jobtracker.monitor.JobTrackerMonitor;
 import com.lts.jobtracker.support.JobDomainConverter;
 import com.lts.queue.domain.JobPo;
 import com.lts.queue.exception.DuplicateJobException;
-import com.lts.remoting.InvokeCallback;
-import com.lts.remoting.netty.ResponseFuture;
+import com.lts.remoting.Channel;
+import com.lts.remoting.AsyncCallback;
+import com.lts.remoting.ResponseFuture;
 import com.lts.remoting.protocol.RemotingCommand;
 import com.lts.remoting.protocol.RemotingProtos;
-import io.netty.channel.Channel;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -139,7 +139,7 @@ public class ExecutingDeadJobChecker {
             JobAskRequest requestBody = application.getCommandBodyWrapper().wrapper(new JobAskRequest());
             requestBody.setJobIds(jobIds);
             RemotingCommand request = RemotingCommand.createRequestCommand(JobProtos.RequestCode.JOB_ASK.code(), requestBody);
-            remotingServer.invokeAsync(channel, request, new InvokeCallback() {
+            remotingServer.invokeAsync(channel, request, new AsyncCallback() {
                 @Override
                 public void operationComplete(ResponseFuture responseFuture) {
                     RemotingCommand response = responseFuture.getResponseCommand();
@@ -184,7 +184,7 @@ public class ExecutingDeadJobChecker {
                 application.getExecutableJobQueue().add(jobPo);
             } catch (DuplicateJobException e) {
                 // ignore
-                LOGGER.warn(e.getMessage(), e);
+                LOGGER.warn("Add Executable Job error jobPo={}", JSONUtils.toJSONString(jobPo), e);
             }
 
             // 2. remove from executing queue

+ 2 - 2
lts-tasktracker/src/main/java/com/lts/tasktracker/TaskTracker.java

@@ -3,7 +3,7 @@ package com.lts.tasktracker;
 import com.lts.core.cluster.AbstractClientNode;
 import com.lts.core.constant.Constants;
 import com.lts.core.constant.Level;
-import com.lts.remoting.netty.NettyRequestProcessor;
+import com.lts.remoting.RemotingProcessor;
 import com.lts.tasktracker.domain.TaskTrackerApplication;
 import com.lts.tasktracker.domain.TaskTrackerNode;
 import com.lts.tasktracker.monitor.StopWorkingMonitor;
@@ -52,7 +52,7 @@ public class TaskTracker extends AbstractClientNode<TaskTrackerNode, TaskTracker
     }
 
     @Override
-    protected NettyRequestProcessor getDefaultProcessor() {
+    protected RemotingProcessor getDefaultProcessor() {
         return new RemotingDispatcher(application);
     }
 

+ 3 - 3
lts-tasktracker/src/main/java/com/lts/tasktracker/logger/BizLoggerImpl.java

@@ -11,9 +11,9 @@ import com.lts.core.protocol.command.CommandBodyWrapper;
 import com.lts.core.remoting.RemotingClientDelegate;
 import com.lts.core.support.RetryScheduler;
 import com.lts.core.support.SystemClock;
-import com.lts.remoting.InvokeCallback;
+import com.lts.remoting.AsyncCallback;
 import com.lts.remoting.common.Pair;
-import com.lts.remoting.netty.ResponseFuture;
+import com.lts.remoting.ResponseFuture;
 import com.lts.remoting.protocol.RemotingCommand;
 import com.lts.tasktracker.domain.TaskTrackerApplication;
 
@@ -118,7 +118,7 @@ public class BizLoggerImpl implements BizLogger {
         RemotingCommand request = RemotingCommand.createRequestCommand(JobProtos.RequestCode.BIZ_LOG_SEND.code(), requestBody);
         try {
             // 有可能down机,日志丢失
-            remotingClient.invokeAsync(request, new InvokeCallback() {
+            remotingClient.invokeAsync(request, new AsyncCallback() {
                 @Override
                 public void operationComplete(ResponseFuture responseFuture) {
                     RemotingCommand response = responseFuture.getResponseCommand();

+ 2 - 2
lts-tasktracker/src/main/java/com/lts/tasktracker/processor/AbstractProcessor.java

@@ -1,12 +1,12 @@
 package com.lts.tasktracker.processor;
 
-import com.lts.remoting.netty.NettyRequestProcessor;
+import com.lts.remoting.RemotingProcessor;
 import com.lts.tasktracker.domain.TaskTrackerApplication;
 
 /**
  * @author Robert HG (254963746@qq.com) on 8/16/14.
  */
-public abstract class AbstractProcessor implements NettyRequestProcessor {
+public abstract class AbstractProcessor implements RemotingProcessor {
 
     protected TaskTrackerApplication application;
 

+ 2 - 2
lts-tasktracker/src/main/java/com/lts/tasktracker/processor/JobAskProcessor.java

@@ -3,11 +3,11 @@ package com.lts.tasktracker.processor;
 import com.lts.core.protocol.command.CommandBodyWrapper;
 import com.lts.core.protocol.command.JobAskRequest;
 import com.lts.core.protocol.command.JobAskResponse;
+import com.lts.remoting.Channel;
 import com.lts.remoting.exception.RemotingCommandException;
 import com.lts.remoting.protocol.RemotingCommand;
 import com.lts.remoting.protocol.RemotingProtos;
 import com.lts.tasktracker.domain.TaskTrackerApplication;
-import io.netty.channel.ChannelHandlerContext;
 
 import java.util.List;
 
@@ -21,7 +21,7 @@ public class JobAskProcessor extends AbstractProcessor {
     }
 
     @Override
-    public RemotingCommand processRequest(ChannelHandlerContext ctx,
+    public RemotingCommand processRequest(Channel channel,
                                           RemotingCommand request) throws RemotingCommandException {
 
         JobAskRequest requestBody = request.getBody();

+ 5 - 5
lts-tasktracker/src/main/java/com/lts/tasktracker/processor/JobPushProcessor.java

@@ -14,16 +14,16 @@ import com.lts.core.remoting.RemotingClientDelegate;
 import com.lts.core.support.LoggerName;
 import com.lts.core.support.RetryScheduler;
 import com.lts.core.support.SystemClock;
-import com.lts.remoting.InvokeCallback;
+import com.lts.remoting.Channel;
+import com.lts.remoting.AsyncCallback;
+import com.lts.remoting.ResponseFuture;
 import com.lts.remoting.exception.RemotingCommandException;
-import com.lts.remoting.netty.ResponseFuture;
 import com.lts.remoting.protocol.RemotingCommand;
 import com.lts.remoting.protocol.RemotingProtos;
 import com.lts.tasktracker.domain.Response;
 import com.lts.tasktracker.domain.TaskTrackerApplication;
 import com.lts.tasktracker.expcetion.NoAvailableJobRunnerException;
 import com.lts.tasktracker.runner.RunnerCallback;
-import io.netty.channel.ChannelHandlerContext;
 
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
@@ -63,7 +63,7 @@ public class JobPushProcessor extends AbstractProcessor {
     }
 
     @Override
-    public RemotingCommand processRequest(ChannelHandlerContext ctx,
+    public RemotingCommand processRequest(Channel channel,
                                           final RemotingCommand request) throws RemotingCommandException {
 
         JobPushRequest requestBody = request.getBody();
@@ -108,7 +108,7 @@ public class JobPushProcessor extends AbstractProcessor {
 
             try {
                 final CountDownLatch latch = new CountDownLatch(1);
-                remotingClient.invokeAsync(request, new InvokeCallback() {
+                remotingClient.invokeAsync(request, new AsyncCallback() {
                     @Override
                     public void operationComplete(ResponseFuture responseFuture) {
                         try {

+ 7 - 7
lts-tasktracker/src/main/java/com/lts/tasktracker/processor/RemotingDispatcher.java

@@ -1,23 +1,23 @@
 package com.lts.tasktracker.processor;
 
 import com.lts.core.protocol.JobProtos;
+import com.lts.remoting.Channel;
+import com.lts.remoting.RemotingProcessor;
 import com.lts.remoting.exception.RemotingCommandException;
-import com.lts.remoting.netty.NettyRequestProcessor;
 import com.lts.remoting.protocol.RemotingCommand;
 import com.lts.remoting.protocol.RemotingProtos;
 import com.lts.tasktracker.domain.TaskTrackerApplication;
-import io.netty.channel.ChannelHandlerContext;
 
 import java.util.HashMap;
 import java.util.Map;
 
 /**
  * @author Robert HG (254963746@qq.com) on 8/14/14.
- * task tracker 总的处理器, 每一种命令对应不同的处理器
+ *         task tracker 总的处理器, 每一种命令对应不同的处理器
  */
 public class RemotingDispatcher extends AbstractProcessor {
 
-    private final Map<JobProtos.RequestCode, NettyRequestProcessor> processors = new HashMap<JobProtos.RequestCode, NettyRequestProcessor>();
+    private final Map<JobProtos.RequestCode, RemotingProcessor> processors = new HashMap<JobProtos.RequestCode, RemotingProcessor>();
 
     public RemotingDispatcher(TaskTrackerApplication application) {
         super(application);
@@ -26,15 +26,15 @@ public class RemotingDispatcher extends AbstractProcessor {
     }
 
     @Override
-    public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) throws RemotingCommandException {
+    public RemotingCommand processRequest(Channel channel, RemotingCommand request) throws RemotingCommandException {
 
         JobProtos.RequestCode code = JobProtos.RequestCode.valueOf(request.getCode());
-        NettyRequestProcessor processor = processors.get(code);
+        RemotingProcessor processor = processors.get(code);
         if (processor == null) {
             return RemotingCommand.createResponseCommand(RemotingProtos.ResponseCode.REQUEST_CODE_NOT_SUPPORTED.code(),
                     "request code not supported!");
         }
-        return processor.processRequest(ctx, request);
+        return processor.processRequest(channel, request);
     }
 
 }