├── fast-netty ├── protobuf │ ├── desc.png │ ├── protoc.exe │ ├── Protobuf.proto │ ├── LUAcreate.bat │ ├── protoc.bat │ └── JAVAcreate.bat ├── .settings │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.core.resources.prefs │ └── org.eclipse.jdt.core.prefs ├── src │ └── main │ │ ├── java │ │ └── com │ │ │ ├── core │ │ │ ├── dispatcher │ │ │ │ ├── disruptor │ │ │ │ │ ├── MsgEvent.java │ │ │ │ │ ├── MsgEventFactory.java │ │ │ │ │ └── DisruptorManager.java │ │ │ │ ├── annotation │ │ │ │ │ └── HandlerMsg.java │ │ │ │ ├── HandlerRegister.java │ │ │ │ ├── BaseHandler.java │ │ │ │ └── MessageDispatcher.java │ │ │ ├── cluster │ │ │ │ ├── strategy │ │ │ │ │ ├── Strategy.java │ │ │ │ │ ├── OrderLoopStrategy.java │ │ │ │ │ └── RandomStrategy.java │ │ │ │ ├── ServiceRegister.java │ │ │ │ ├── Service.java │ │ │ │ ├── ClusterDispatcher.java │ │ │ │ └── ClusterManager.java │ │ │ ├── netty │ │ │ │ ├── bootstrap │ │ │ │ │ ├── inter │ │ │ │ │ │ ├── IClient.java │ │ │ │ │ │ └── IServer.java │ │ │ │ │ ├── client │ │ │ │ │ │ ├── HandlerHolder.java │ │ │ │ │ │ ├── pool │ │ │ │ │ │ │ ├── TcpClientChannel.java │ │ │ │ │ │ │ ├── SimpleTcpClient.java │ │ │ │ │ │ │ ├── TcpClientChannelPool.java │ │ │ │ │ │ │ ├── PooledClient.java │ │ │ │ │ │ │ ├── TcpClientFactory.java │ │ │ │ │ │ │ └── PooledConfig.java │ │ │ │ │ │ ├── ClientHandler.java │ │ │ │ │ │ ├── ReConnHandler.java │ │ │ │ │ │ └── TcpClient.java │ │ │ │ │ └── server │ │ │ │ │ │ ├── ServerIdleHandler.java │ │ │ │ │ │ ├── ServerHandler.java │ │ │ │ │ │ └── TcpServer.java │ │ │ │ └── coder │ │ │ │ │ ├── Encoder.java │ │ │ │ │ ├── Decoder.java │ │ │ │ │ └── Message.java │ │ │ ├── util │ │ │ │ ├── HostsParser.java │ │ │ │ └── Pool.java │ │ │ ├── thread │ │ │ │ ├── ExecutorPool.java │ │ │ │ └── NameThreadFactory.java │ │ │ └── session │ │ │ │ └── Session.java │ │ │ ├── example │ │ │ ├── DemoServer.java │ │ │ ├── cluster │ │ │ │ ├── C1Server2.java │ │ │ │ ├── C1Server.java │ │ │ │ └── C1Client.java │ │ │ ├── PoolClient3.java │ │ │ ├── DemoClient2.java │ │ │ ├── DomeClientHandler.java │ │ │ ├── DemoClient.java │ │ │ └── DomeServerHandler.java │ │ │ └── protobuf │ │ │ └── Protobuf.java │ │ └── resources │ │ └── logback.xml ├── .gitignore ├── .project ├── .classpath └── pom.xml ├── .gitignore └── README.md /fast-netty/protobuf/desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qihang666/fast-netty/HEAD/fast-netty/protobuf/desc.png -------------------------------------------------------------------------------- /fast-netty/protobuf/protoc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qihang666/fast-netty/HEAD/fast-netty/protobuf/protoc.exe -------------------------------------------------------------------------------- /fast-netty/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /fast-netty/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /fast-netty/protobuf/Protobuf.proto: -------------------------------------------------------------------------------- 1 | //option java_outer_classname = "Message"; 2 | option java_package = "com.protobuf"; 3 | 4 | package dough.protocol; 5 | 6 | message TestData{ 7 | optional int32 age = 1; 8 | optional string name = 2; 9 | optional int32 id = 3; 10 | 11 | } 12 | 13 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/dispatcher/disruptor/MsgEvent.java: -------------------------------------------------------------------------------- 1 | package com.core.dispatcher.disruptor; 2 | 3 | public class MsgEvent { 4 | private T value; 5 | 6 | public T get() { 7 | return value; 8 | } 9 | 10 | public void set(T value) { 11 | this.value = value; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /fast-netty/protobuf/LUAcreate.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | set DIR=%~dp0 3 | cd /d "%DIR%" 4 | setlocal enabledelayedexpansion 5 | for /r %%i in (*.proto) do ( 6 | set pbname=%%i 7 | set pbname=!pbname:~0,-5!b 8 | protoc -I %DIR% --descriptor_set_out !pbname! %%i 9 | ) 10 | echo "----------SUCCEED---------" 11 | pause -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/dispatcher/disruptor/MsgEventFactory.java: -------------------------------------------------------------------------------- 1 | package com.core.dispatcher.disruptor; 2 | 3 | import com.lmax.disruptor.EventFactory; 4 | 5 | public class MsgEventFactory implements EventFactory>{ 6 | 7 | @Override 8 | public MsgEvent newInstance() { 9 | return new MsgEvent(); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /fast-netty/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/cluster/strategy/Strategy.java: -------------------------------------------------------------------------------- 1 | package com.core.cluster.strategy; 2 | 3 | import java.util.Set; 4 | 5 | import com.core.cluster.Service; 6 | 7 | /** 8 | * 服务发现策略 接口 9 | * @Description: 10 | * @author: hang 11 | * @date: 2018年9月10日下午5:58:21 12 | * @version V1.7 13 | */ 14 | public interface Strategy { 15 | 16 | Service discovery(Set set); 17 | } 18 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/bootstrap/inter/IClient.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.bootstrap.inter; 2 | 3 | public interface IClient { 4 | /** 5 | * 初始化 6 | */ 7 | void init(); 8 | 9 | /** 10 | * 启动 11 | */ 12 | void start(); 13 | 14 | /** 15 | * 关闭 16 | */ 17 | void stop(); 18 | 19 | /** 20 | * 写数据 21 | * @param msg 22 | */ 23 | void writeAndFlush(Object msg); 24 | } 25 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/bootstrap/inter/IServer.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.bootstrap.inter; 2 | 3 | public interface IServer { 4 | /** 5 | * 初始化 6 | */ 7 | void init(); 8 | 9 | /** 10 | * 启动 11 | */ 12 | void start(); 13 | 14 | /** 15 | * 关闭 16 | */ 17 | void stop(); 18 | 19 | /** 20 | * 监听端口 21 | * @param port 22 | * @return 23 | */ 24 | IServer listen(int port); 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | .metadata 21 | *.AppTest.xml 22 | target 23 | log 24 | logs 25 | lib 26 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 27 | hs_err_pid* 28 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/bootstrap/client/HandlerHolder.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.bootstrap.client; 2 | 3 | import io.netty.channel.ChannelHandler; 4 | 5 | /** 6 | * 7 | * 客户端的ChannelHandler集合,由子类实现,这样做的好处: 8 | * 继承这个接口的所有子类可以很方便地获取ChannelPipeline中的Handlers 9 | * 获取到handlers之后方便ChannelPipeline中的handler的初始化和在重连的时候也能很方便 10 | * 地获取所有的handlers 11 | */ 12 | public interface HandlerHolder { 13 | 14 | ChannelHandler[] handlers(); 15 | } 16 | -------------------------------------------------------------------------------- /fast-netty/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/example/DemoServer.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.core.dispatcher.MessageDispatcher; 4 | import com.core.netty.bootstrap.server.TcpServer; 5 | 6 | public class DemoServer extends TcpServer { 7 | 8 | 9 | 10 | @Override 11 | public void init() { 12 | 13 | } 14 | 15 | public static void main(String[] args) { 16 | MessageDispatcher.register(DomeServerHandler.class); 17 | 18 | new DemoServer().listen(9000).start(); 19 | 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/dispatcher/annotation/HandlerMsg.java: -------------------------------------------------------------------------------- 1 | package com.core.dispatcher.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | /** 8 | * 消息处理注解 9 | * @Description: 10 | * @author: hang 11 | * @date: 2018年9月5日下午3:11:13 12 | * @version V1.8 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(ElementType.METHOD) 16 | public @interface HandlerMsg { 17 | 18 | public short id();//协议Id号 19 | 20 | } 21 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/bootstrap/client/pool/TcpClientChannel.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.bootstrap.client.pool; 2 | 3 | import io.netty.channel.ChannelFuture; 4 | 5 | public class TcpClientChannel { 6 | ChannelFuture channelFuture; 7 | 8 | 9 | public TcpClientChannel(ChannelFuture channelFuture) { 10 | super(); 11 | this.channelFuture = channelFuture; 12 | } 13 | 14 | public ChannelFuture getChannelFuture() { 15 | return channelFuture; 16 | } 17 | 18 | public void setChannelFuture(ChannelFuture channelFuture) { 19 | this.channelFuture = channelFuture; 20 | } 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /fast-netty/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | fast-netty 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /fast-netty/protobuf/protoc.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo ** setting runtime variable 3 | 4 | REM _protoSrc �����proto�ļ�Ŀ¼��λ�� 5 | set _protoSrc=D:\project\server\dough-base\protobuf\source 6 | 7 | REM protoExe �����ڴ�proto���java��protoc.exe�����λ�� 8 | set protoExe=D:\project\server\dough-base\protobuf\protoc.exe 9 | 10 | REM java_out_file �����ɵ�Java�ļ�Ŀ¼��λ�� 11 | set java_out_file=D:\project\server\dough-base\src\main\java 12 | 13 | for /R "%_protoSrc%" %%i in (*) do ( 14 | set filename=%%~nxi 15 | if "%%~xi" == ".proto" ( 16 | %protoExe% --proto_path=%_protoSrc% --java_out=%java_out_file% %%i 17 | ) 18 | ) 19 | pause -------------------------------------------------------------------------------- /fast-netty/protobuf/JAVAcreate.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo ** setting runtime variable 3 | 4 | REM _protoSrc �����proto�ļ�Ŀ¼��λ�� 5 | set _protoSrc=D:\\gameWork\\game-core\\protobuf 6 | 7 | REM protoExe �����ڴ�proto���java��protoc.exe�����λ�� 8 | set protoExe=D:\\gameWork\\game-core\\protobuf\protoc.exe 9 | 10 | REM java_out_file �����ɵ�Java�ļ�Ŀ¼��λ�� 11 | set java_out_file=D:\\gameWork\\game-core\\src\\main\\java 12 | 13 | for /R "%_protoSrc%" %%i in (*) do ( 14 | set filename=%%~nxi 15 | if "%%~xi" == ".proto" ( 16 | %protoExe% --proto_path=%_protoSrc% --java_out=%java_out_file% %%i 17 | ) 18 | ) 19 | echo "----------SUCCEED---------" 20 | pause -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/cluster/strategy/OrderLoopStrategy.java: -------------------------------------------------------------------------------- 1 | package com.core.cluster.strategy; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Set; 5 | 6 | import com.core.cluster.Service; 7 | 8 | /** 9 | * 轮训策略 10 | * 11 | * @Description: 12 | * @author: hang 13 | * @date: 2018年9月10日下午6:51:55 14 | * @version V1.7 15 | */ 16 | public class OrderLoopStrategy implements Strategy { 17 | 18 | private int index = 0; 19 | 20 | @Override 21 | public Service discovery(Set set) { 22 | if (index >= set.size()) { 23 | index = 0; 24 | } 25 | Service service = new ArrayList<>(set).get(index); 26 | index++; 27 | return service; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/cluster/strategy/RandomStrategy.java: -------------------------------------------------------------------------------- 1 | package com.core.cluster.strategy; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Random; 5 | import java.util.Set; 6 | 7 | import com.core.cluster.Service; 8 | /** 9 | * 随机策略 10 | * @Description: 11 | * @author: hang 12 | * @date: 2018年9月10日下午6:51:55 13 | * @version V1.7 14 | */ 15 | public class RandomStrategy implements Strategy { 16 | 17 | private Random rand = new Random(); 18 | 19 | @Override 20 | public Service discovery(Set set) { 21 | int index = rand.nextInt(set.size()); 22 | Service service = new ArrayList<>(set).get(index); 23 | return service; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/dispatcher/HandlerRegister.java: -------------------------------------------------------------------------------- 1 | package com.core.dispatcher; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * 需要注册的处理类 8 | * @Description: 9 | * @author: hang 10 | * @date: 2018年9月7日下午2:19:04 11 | * @version V1.7 12 | */ 13 | public class HandlerRegister { 14 | 15 | private List> alasszs = new ArrayList<>(); 16 | 17 | public void register(Class classz){ 18 | alasszs.add(classz); 19 | } 20 | 21 | public void register(Class... classz){ 22 | for(Class c: classz) { 23 | alasszs.add(c); 24 | } 25 | } 26 | 27 | public List> getAlasszs() { 28 | return alasszs; 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/coder/Encoder.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.coder; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.handler.codec.MessageToByteEncoder; 6 | 7 | public class Encoder extends MessageToByteEncoder { 8 | 9 | @Override 10 | protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) throws Exception { 11 | if (null == msg) { 12 | throw new Exception("msg is null"); 13 | } 14 | int length = 2; 15 | if (msg.getBody() != null) { 16 | length =length+ msg.getBody().length; 17 | } 18 | out.writeInt(length); 19 | out.writeShort(msg.getId()); 20 | if (msg.getBody() != null) { 21 | out.writeBytes(msg.getBody());// 2进制数据 22 | } 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/util/HostsParser.java: -------------------------------------------------------------------------------- 1 | package com.core.util; 2 | /** 3 | * 主机地址解析器 4 | * @Description: 5 | * @author: hang 6 | * @date: 2018年9月11日下午6:55:02 7 | * @version V1.7 8 | */ 9 | public class HostsParser { 10 | private String hosts; 11 | private int port; 12 | 13 | public HostsParser(String address){ 14 | String []sp = address.split(":"); 15 | if(sp.length==2) { 16 | hosts = sp[0]; 17 | port = Integer.valueOf(sp[1]); 18 | } 19 | } 20 | 21 | public String getHosts() { 22 | return hosts; 23 | } 24 | 25 | public void setHosts(String hosts) { 26 | this.hosts = hosts; 27 | } 28 | 29 | public int getPort() { 30 | return port; 31 | } 32 | 33 | public void setPort(int port) { 34 | this.port = port; 35 | } 36 | 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/example/cluster/C1Server2.java: -------------------------------------------------------------------------------- 1 | package com.example.cluster; 2 | 3 | import com.core.cluster.ClusterManager; 4 | import com.core.cluster.Service; 5 | import com.core.dispatcher.MessageDispatcher; 6 | import com.core.netty.bootstrap.server.TcpServer; 7 | import com.example.DomeServerHandler; 8 | 9 | public class C1Server2 extends TcpServer { 10 | 11 | 12 | 13 | @Override 14 | public void init() { 15 | 16 | } 17 | 18 | public static void main(String[] args) { 19 | MessageDispatcher.register(DomeServerHandler.class); 20 | ClusterManager ha = new ClusterManager("127.0.0.1:2100"); 21 | Service s = new Service("mate2","127.0.0.1",9001,2); 22 | ha.registerService(s.getServiceId(), s); 23 | new C1Server2().listen(9001).start(); 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/example/cluster/C1Server.java: -------------------------------------------------------------------------------- 1 | package com.example.cluster; 2 | 3 | import com.core.cluster.ClusterManager; 4 | import com.core.cluster.Service; 5 | import com.core.dispatcher.MessageDispatcher; 6 | import com.core.netty.bootstrap.server.TcpServer; 7 | import com.example.DomeServerHandler; 8 | 9 | public class C1Server extends TcpServer { 10 | 11 | 12 | 13 | @Override 14 | public void init() { 15 | 16 | } 17 | 18 | public static void main(String[] args) { 19 | MessageDispatcher.register(DomeServerHandler.class); 20 | ClusterManager ha = new ClusterManager("127.0.0.1:2100"); 21 | Service s = new Service("mate1","127.0.0.1",9000,2); 22 | ha.registerService(s.getServiceId(), s); 23 | new C1Server().listen(9000).start(); 24 | 25 | 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/bootstrap/client/pool/SimpleTcpClient.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.bootstrap.client.pool; 2 | 3 | import com.core.dispatcher.HandlerRegister; 4 | import com.core.dispatcher.MessageDispatcher; 5 | import com.core.netty.bootstrap.client.TcpClient; 6 | 7 | public class SimpleTcpClient extends TcpClient { 8 | public SimpleTcpClient(String hosts,int port ) { 9 | super(hosts, port); 10 | } 11 | public SimpleTcpClient(String hosts,int port,HandlerRegister register) { 12 | super(hosts, port); 13 | this.register = register; 14 | init(); 15 | } 16 | 17 | @Override 18 | public void init() { 19 | if(register!= null && !register.getAlasszs().isEmpty()) { 20 | for (Class c : register.getAlasszs()) { 21 | MessageDispatcher.register(c); 22 | } 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/example/PoolClient3.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.core.dispatcher.MessageDispatcher; 4 | import com.core.netty.bootstrap.client.pool.PooledClient; 5 | import com.core.netty.bootstrap.inter.IClient; 6 | import com.core.netty.coder.Message; 7 | import com.protobuf.Protobuf; 8 | 9 | public class PoolClient3 { 10 | 11 | 12 | 13 | public static void main(String[] args) { 14 | MessageDispatcher.register(DomeClientHandler.class); 15 | IClient c = new PooledClient("127.0.0.1", 9000); 16 | int i = 0; 17 | Protobuf.TestData.Builder data = Protobuf.TestData.newBuilder(); 18 | while(i<20001) { 19 | data.clear(); 20 | data.setName("name"+i++); 21 | data.setId(i); 22 | Message m2 = new Message((short)10,data.build().toByteArray()); 23 | c.writeAndFlush(m2); 24 | // c.getChannel().write(m2); 25 | // if(i%2000==0) { 26 | // c.getChannel().flush(); 27 | // } 28 | } 29 | 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/bootstrap/client/pool/TcpClientChannelPool.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.bootstrap.client.pool; 2 | 3 | import org.apache.commons.pool.impl.GenericObjectPool.Config; 4 | 5 | import com.core.dispatcher.HandlerRegister; 6 | import com.core.util.Pool; 7 | 8 | /** 9 | * 客户端连接池 10 | * 11 | * @Description: 12 | * @author: hang 13 | * @date: 2018年9月7日下午2:39:08 14 | * @version V1.7 15 | */ 16 | public class TcpClientChannelPool extends Pool { 17 | 18 | /** 19 | * 20 | * @param poolConfig 21 | * 连接池配置 22 | * @param port 23 | * 主机端口号 24 | * @param hosts 25 | * 主机地址 26 | * @param register 27 | * 注册的处理类 28 | */ 29 | public TcpClientChannelPool(Config poolConfig, int port, String hosts, HandlerRegister register) { 30 | super(poolConfig == null ? new PooledConfig().getPoolConfig() : poolConfig, 31 | new TcpClientFactory(port, hosts, register, false)); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/example/DemoClient2.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.core.dispatcher.MessageDispatcher; 4 | import com.core.netty.bootstrap.client.TcpClient; 5 | import com.core.netty.coder.Message; 6 | import com.protobuf.Protobuf; 7 | 8 | public class DemoClient2 extends TcpClient { 9 | 10 | public DemoClient2(String hosts, int port) { 11 | super(hosts, port); 12 | } 13 | 14 | 15 | @Override 16 | public void init() { 17 | MessageDispatcher.register(DomeClientHandler.class); 18 | } 19 | 20 | 21 | public static void main(String[] args) { 22 | DemoClient2 c = new DemoClient2("127.0.0.1",9000); 23 | c.start(); 24 | int i=0; 25 | Protobuf.TestData.Builder data = Protobuf.TestData.newBuilder(); 26 | while(i<20001) { 27 | data.clear(); 28 | data.setName("name"+i++); 29 | data.setId(i); 30 | Message m2 = new Message((short)10,data.build().toByteArray()); 31 | c.getChannel().writeAndFlush(m2); 32 | // c.getChannel().write(m2); 33 | // if(i%2000==0) { 34 | // c.getChannel().flush(); 35 | // } 36 | } 37 | 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/example/DomeClientHandler.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.core.dispatcher.annotation.HandlerMsg; 4 | import com.core.netty.coder.Message; 5 | import com.google.protobuf.InvalidProtocolBufferException; 6 | import com.protobuf.Protobuf; 7 | import com.protobuf.Protobuf.TestData; 8 | 9 | public class DomeClientHandler { 10 | public static DomeClientHandler instance = new DomeClientHandler(); 11 | 12 | public static DomeClientHandler getInstance() { 13 | return instance; 14 | } 15 | 16 | @HandlerMsg(id = 10) 17 | public void test1(Message msg) { 18 | try { 19 | TestData data = Protobuf.TestData.parseFrom(msg.getBody()); 20 | System.err.println(data.getName()); 21 | 22 | } catch (Exception e) { 23 | e.printStackTrace(); 24 | } 25 | 26 | } 27 | 28 | @HandlerMsg(id = 11) 29 | public void test2(Message msg) { 30 | try { 31 | TestData data = Protobuf.TestData.parseFrom(msg.getBody()); 32 | System.err.println("消息11:"+data.getName()); 33 | } catch (InvalidProtocolBufferException e) { 34 | e.printStackTrace(); 35 | } 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/coder/Decoder.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.coder; 2 | 3 | import java.util.List; 4 | 5 | import io.netty.buffer.ByteBuf; 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.handler.codec.ByteToMessageDecoder; 8 | 9 | public class Decoder extends ByteToMessageDecoder{ 10 | 11 | 12 | @Override 13 | protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { 14 | if (in == null) { 15 | return; 16 | } 17 | if (in.readableBytes() < Message.HEADER_SIZE) { 18 | return; 19 | } 20 | in.markReaderIndex(); 21 | int lenght = in.readInt(); 22 | if (in.readableBytes() < lenght) { 23 | in.resetReaderIndex(); 24 | return; 25 | } 26 | 27 | short id = in.readShort(); 28 | byte[] content = null; 29 | lenght = lenght-2; 30 | if(lenght > 0){ 31 | content = new byte[lenght]; 32 | in.readBytes(content,0,lenght); 33 | } 34 | Message msg = new Message(id,content); 35 | out.add(msg); 36 | 37 | 38 | } 39 | 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/coder/Message.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.coder; 2 | 3 | import com.core.session.Session; 4 | 5 | public class Message { 6 | 7 | public static final int HEADER_SIZE = 4; 8 | 9 | private short id;//协议id 10 | private int length;//长度 11 | private byte[] body; //内容 12 | private Session session;//会话 13 | 14 | public Message() { 15 | } 16 | 17 | public Message(short id, byte[] body) { 18 | this.id = id; 19 | this.body = body; 20 | } 21 | 22 | public short getId() { 23 | return id; 24 | } 25 | 26 | public Message setId(short id) { 27 | this.id = id; 28 | return this; 29 | } 30 | 31 | public byte[] getBody() { 32 | return body; 33 | } 34 | 35 | public Message setBody(byte[] body) { 36 | this.body = body; 37 | return this; 38 | } 39 | 40 | public int getLength() { 41 | return length; 42 | } 43 | 44 | public Message setLength(int length) { 45 | this.length = length; 46 | return this; 47 | } 48 | 49 | public Session getSession() { 50 | return session; 51 | } 52 | 53 | public void setSession(Session session) { 54 | this.session = session; 55 | } 56 | 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fast-netty 2 | java服务器快速上手的网络IO框架,基于netty, google protobuf 数据传输协议,disruptor队列,zookeeper服务注册发现,用于服务器间长连接通讯,可搭建分布式服务器以及分布式游戏。 3 | 4 | # Server 5 |
 6 | 
 7 | public class DemoServer extends TcpServer {
 8 |        
 9 |       	public static void main(String[] args) {
10 | 		                                       
11 |             MessageDispatcher.register(DomeServerHandler.class);
12 | 		
13 |             new DemoServer().listen(9000).start();
14 | 		
15 |        }
16 | }
17 |     
18 | 
19 | # Client 20 |
21 | 
22 | public class DemoClient extends TcpClient {
23 | 
24 | 	public DemoClient(String hosts, int port) {
25 | 		super(hosts, port);
26 | 	}
27 | 	
28 |   public static void main(String[] args) {
29 |      
30 |         MessageDispatcher.register(DomeClientHandler.class);
31 | 		 
32 |         DemoClient client = new DemoClient("127.0.0.1",9000);
33 | 	   
34 |         client.start();
35 |         
36 | 	      Protobuf.TestData.Builder data = Protobuf.TestData.newBuilder();
37 | 	      data.setName("我是客户端");
38 | 		 
39 |         client.writeAndFlush(new Message((short)11,data.build().toByteArray()));
40 |     
41 |   }
42 | 
43 |    
44 | 
45 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/thread/ExecutorPool.java: -------------------------------------------------------------------------------- 1 | package com.core.thread; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.LinkedBlockingQueue; 6 | import java.util.concurrent.ScheduledExecutorService; 7 | import java.util.concurrent.ThreadPoolExecutor; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | public class ExecutorPool { 11 | 12 | public static ExecutorPool instance = new ExecutorPool(); 13 | public static ExecutorPool getInstance() { 14 | return instance; 15 | } 16 | //定时服务线程 17 | private ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(3); 18 | 19 | // 执行事件处理 线程池 20 | // private ExecutorService threadPool = Executors.newFixedThreadPool(2); 21 | private ExecutorService threadPool = new ThreadPoolExecutor( 22 | 4, 23 | 4, 24 | 0L, 25 | TimeUnit.MILLISECONDS, 26 | new LinkedBlockingQueue(), 27 | new NameThreadFactory("dispatcher msg thread") 28 | ) ; 29 | 30 | public ScheduledExecutorService getScheduledPool() { 31 | return scheduledPool; 32 | } 33 | 34 | public ExecutorService getThreadPool() { 35 | return threadPool; 36 | } 37 | 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/example/cluster/C1Client.java: -------------------------------------------------------------------------------- 1 | package com.example.cluster; 2 | 3 | import com.core.cluster.ClusterDispatcher; 4 | import com.core.cluster.ClusterManager; 5 | import com.core.cluster.Service; 6 | import com.core.cluster.strategy.RandomStrategy; 7 | import com.core.dispatcher.MessageDispatcher; 8 | import com.core.netty.bootstrap.server.TcpServer; 9 | import com.core.netty.coder.Message; 10 | import com.example.DemoClient; 11 | import com.example.DomeClientHandler; 12 | import com.example.DomeServerHandler; 13 | import com.protobuf.Protobuf; 14 | 15 | public class C1Client extends TcpServer { 16 | 17 | 18 | 19 | @Override 20 | public void init() { 21 | 22 | } 23 | 24 | public static void main(String[] args) throws InterruptedException { 25 | MessageDispatcher.register(DomeClientHandler.class); 26 | ClusterDispatcher ha = new ClusterDispatcher("127.0.0.1:2100",new RandomStrategy()); 27 | Protobuf.TestData.Builder data = Protobuf.TestData.newBuilder(); 28 | data.setName("name"); 29 | data.setId(2); 30 | ha.sendFirstMsgByDiscovery("1_2233", 2, (short)10,data.build()); 31 | for(int i=0;i<10;i++) { 32 | ha.sendMsg("1_2233", 2 ,(short)10,data.build()); 33 | Thread.sleep(5000l); 34 | 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/bootstrap/client/ClientHandler.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.bootstrap.client; 2 | 3 | import com.core.dispatcher.MessageDispatcher; 4 | import com.core.dispatcher.disruptor.DisruptorManager; 5 | import com.core.netty.coder.Message; 6 | 7 | import io.netty.channel.ChannelHandlerContext; 8 | import io.netty.channel.SimpleChannelInboundHandler; 9 | 10 | public class ClientHandler extends SimpleChannelInboundHandler{ 11 | 12 | private static ThreadLocal LOCAL = new ThreadLocal() { 13 | @Override 14 | protected DisruptorManager initialValue() { 15 | return new DisruptorManager() { 16 | @Override 17 | public void eventHandler(Message msg, long sequence) { 18 | MessageDispatcher.dispatcher(msg); 19 | } 20 | }; 21 | } 22 | }; 23 | 24 | @Override 25 | protected void channelRead0(ChannelHandlerContext ctx, Message msg) throws Exception { 26 | LOCAL.get().publishEvent(msg); 27 | } 28 | 29 | @Override 30 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 31 | super.channelActive(ctx); 32 | } 33 | 34 | @Override 35 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 36 | super.channelInactive(ctx); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/session/Session.java: -------------------------------------------------------------------------------- 1 | package com.core.session; 2 | 3 | import com.core.netty.coder.Message; 4 | import com.google.protobuf.GeneratedMessage; 5 | 6 | import io.netty.channel.Channel; 7 | /** 8 | * 会话 9 | * @Description: 10 | * @author: hang 11 | * @date: 2018年9月6日下午6:53:00 12 | * @version V1.7 13 | */ 14 | public class Session { 15 | 16 | private Channel channel; 17 | 18 | public Session() {} 19 | public Session(Channel channel) { 20 | this.channel = channel; 21 | } 22 | 23 | public Channel getChannel() { 24 | return channel; 25 | } 26 | 27 | public void setChannel(Channel channel) { 28 | this.channel = channel; 29 | } 30 | 31 | public void write(Object msg) { 32 | if (channel != null) { 33 | if (channel.isActive()) { 34 | channel.write(msg); 35 | } 36 | } 37 | } 38 | 39 | public void writeMessage(short id,GeneratedMessage msg) { 40 | if (channel != null) { 41 | if (channel.isActive()) { 42 | Message m = new Message(id,msg.toByteArray()); 43 | channel.writeAndFlush(m); 44 | } 45 | } 46 | } 47 | 48 | public void writeAndFlush(Object msg) { 49 | if (channel != null) { 50 | if (channel.isActive()) { 51 | channel.writeAndFlush(msg); 52 | } 53 | } 54 | } 55 | 56 | 57 | } 58 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/thread/NameThreadFactory.java: -------------------------------------------------------------------------------- 1 | package com.core.thread; 2 | 3 | import java.util.concurrent.ThreadFactory; 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | 6 | public class NameThreadFactory implements ThreadFactory { 7 | private static final AtomicInteger poolNumber = new AtomicInteger(1); 8 | private final ThreadGroup group; 9 | private final AtomicInteger threadNumber = new AtomicInteger(1); 10 | private final String namePrefix; 11 | 12 | public NameThreadFactory(String name) { 13 | SecurityManager s = System.getSecurityManager(); 14 | group = (s != null) ? s.getThreadGroup() : 15 | Thread.currentThread().getThreadGroup(); 16 | namePrefix = name+"-" + 17 | poolNumber.getAndIncrement() + 18 | "-thread-"; 19 | } 20 | 21 | public Thread newThread(Runnable r) { 22 | Thread t = new Thread(group, r, 23 | namePrefix + threadNumber.getAndIncrement(), 24 | 0); 25 | if (t.isDaemon()) 26 | t.setDaemon(false); 27 | if (t.getPriority() != Thread.NORM_PRIORITY) 28 | t.setPriority(Thread.NORM_PRIORITY); 29 | return t; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/example/DemoClient.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import java.util.Scanner; 4 | 5 | import com.core.dispatcher.MessageDispatcher; 6 | import com.core.netty.bootstrap.client.TcpClient; 7 | import com.core.netty.coder.Message; 8 | import com.protobuf.Protobuf; 9 | 10 | public class DemoClient extends TcpClient { 11 | 12 | public DemoClient(String hosts, int port) { 13 | super(hosts, port); 14 | } 15 | 16 | 17 | 18 | @Override 19 | public void init() { 20 | MessageDispatcher.register(DomeClientHandler.class); 21 | 22 | } 23 | 24 | 25 | 26 | public static void main(String[] args) { 27 | DemoClient client = new DemoClient("127.0.0.1",9000); 28 | client.start(); 29 | Protobuf.TestData.Builder data = Protobuf.TestData.newBuilder(); 30 | data.setName("我是客户端"); 31 | client.writeAndFlush(new Message((short)11,data.build().toByteArray())); 32 | for (; ; ) { 33 | Scanner scan = new Scanner(System.in); 34 | String msg = scan.nextLine(); 35 | if ("exit".equals(msg)) { 36 | System.exit(0); 37 | } 38 | Protobuf.TestData.Builder data2 = Protobuf.TestData.newBuilder(); 39 | data2.setName(msg); 40 | client.writeAndFlush(new Message((short)11,data2.build().toByteArray())); 41 | } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/bootstrap/client/pool/PooledClient.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.bootstrap.client.pool; 2 | 3 | import org.apache.commons.pool.impl.GenericObjectPool.Config; 4 | 5 | import com.core.netty.bootstrap.inter.IClient; 6 | /** 7 | * 连接池客户端 8 | * @Description: 9 | * @author: hang 10 | * @date: 2018年9月10日上午11:23:48 11 | * @version V1.7 12 | */ 13 | public class PooledClient implements IClient{ 14 | //连接池对象 15 | private TcpClientChannelPool pools; 16 | 17 | public PooledClient(String hosts,int port) { 18 | this.pools = new TcpClientChannelPool(null, port, hosts, null); 19 | } 20 | 21 | public PooledClient(String hosts,int port,Config poolConfig) { 22 | this.pools = new TcpClientChannelPool(poolConfig, port, hosts, null); 23 | } 24 | 25 | @Override 26 | public void writeAndFlush(Object msg) { 27 | TcpClientChannel resource = this.pools.getResource(); 28 | try { 29 | resource.getChannelFuture().channel().writeAndFlush(msg); 30 | } catch (Exception e) { 31 | throw e; 32 | }finally { 33 | this.pools.returnResource(resource); 34 | } 35 | } 36 | 37 | public TcpClientChannelPool getPools() { 38 | return pools; 39 | } 40 | 41 | @Override 42 | public void init() { 43 | 44 | } 45 | 46 | @Override 47 | public void start() { 48 | } 49 | 50 | @Override 51 | public void stop() { 52 | } 53 | 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/dispatcher/BaseHandler.java: -------------------------------------------------------------------------------- 1 | package com.core.dispatcher; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import com.core.netty.coder.Message; 9 | import com.core.session.Session; 10 | import com.google.protobuf.GeneratedMessage; 11 | 12 | public class BaseHandler { 13 | protected Logger log = LoggerFactory.getLogger(this.getClass()); 14 | 15 | public void sendMsg(short id,GeneratedMessage msg, Session session) { 16 | if(session.getChannel()!= null&&session.getChannel().isActive()) { 17 | Message m = new Message(id, msg.toByteArray()); 18 | session.getChannel().writeAndFlush(m); 19 | } 20 | } 21 | 22 | public void sendMsg(short id,GeneratedMessage msg, Message message) { 23 | sendMsg(id,msg,message.getSession()); 24 | } 25 | 26 | /** 27 | * 转化消息对象 28 | * @param clazz 29 | * @param data 30 | * @return 31 | */ 32 | @SuppressWarnings("unchecked") 33 | public T parseFromMsg(Class clazz, 34 | byte[] data) { 35 | if(data == null){ 36 | return null; 37 | } 38 | GeneratedMessage msg = null; 39 | try { 40 | Method method = clazz.getMethod("parseFrom", byte[].class); 41 | msg = (GeneratedMessage) method.invoke(null, data); 42 | } catch (Exception e) { 43 | log.error("parseFrom error", e); 44 | } 45 | return (T) msg; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/dispatcher/disruptor/DisruptorManager.java: -------------------------------------------------------------------------------- 1 | package com.core.dispatcher.disruptor; 2 | 3 | import com.core.netty.coder.Message; 4 | import com.core.thread.NameThreadFactory; 5 | import com.lmax.disruptor.EventFactory; 6 | import com.lmax.disruptor.EventHandler; 7 | import com.lmax.disruptor.RingBuffer; 8 | import com.lmax.disruptor.dsl.Disruptor; 9 | 10 | public abstract class DisruptorManager { 11 | 12 | private Disruptor> disruptor; 13 | 14 | @SuppressWarnings("unchecked") 15 | public DisruptorManager() { 16 | 17 | EventFactory> eventFactory = new MsgEventFactory(); 18 | int bufferSize = 1024 * 16; 19 | disruptor = new Disruptor>(eventFactory, bufferSize, 20 | new NameThreadFactory("Disruptor")); 21 | disruptor.handleEventsWith(new EventHandler>() { 22 | 23 | @Override 24 | public void onEvent(MsgEvent event, long sequence, boolean endOfBatch) throws Exception { 25 | eventHandler(event.get(),sequence); 26 | } 27 | 28 | }); 29 | disruptor.start(); 30 | 31 | } 32 | 33 | public void publishEvent(Message m) { 34 | RingBuffer> rb = disruptor.getRingBuffer(); 35 | long index = rb.next(); 36 | MsgEvent event = rb.get(index); 37 | event.set(m); 38 | rb.publish(index); 39 | } 40 | 41 | 42 | public abstract void eventHandler(Message msg,long sequence); 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/bootstrap/server/ServerIdleHandler.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.bootstrap.server; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import io.netty.channel.ChannelDuplexHandler; 7 | import io.netty.channel.ChannelHandlerContext; 8 | import io.netty.handler.timeout.IdleState; 9 | import io.netty.handler.timeout.IdleStateEvent; 10 | /** 11 | * 读取数据超时处理 12 | * @Description: 13 | * @author: hang 14 | * @date: 2018年9月6日下午5:55:47 15 | * @version V1.7 16 | */ 17 | public class ServerIdleHandler extends ChannelDuplexHandler{ 18 | 19 | public static final int READER_TIME = 60*30;//多久没有数据读取了 关闭通道 避免消耗服务器资源 单位(秒) 20 | // public static final int READER_TIME = 6; 21 | protected Logger log = LoggerFactory.getLogger(this.getClass()); 22 | @Override 23 | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { 24 | if (evt instanceof IdleStateEvent) { 25 | IdleStateEvent e = (IdleStateEvent) evt; 26 | if (e.state() == IdleState.WRITER_IDLE) { 27 | log.info("Write idle on channel:" + ctx.channel() + " is timeout"); 28 | } else if (e.state() == IdleState.READER_IDLE) { 29 | log.info("Read idle on channel:" + ctx.channel() + " is timeout on " 30 | + ctx.channel().remoteAddress() + ", so close it"); 31 | ctx.close(); 32 | } 33 | } 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /fast-netty/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/cluster/ServiceRegister.java: -------------------------------------------------------------------------------- 1 | package com.core.cluster; 2 | 3 | import org.apache.zookeeper.CreateMode; 4 | 5 | /** 6 | * 服务 注册信息 7 | * 8 | * @Description: 9 | * @author: hang 10 | * @date: 2018年9月10日下午4:58:32 11 | * @version V1.7 12 | */ 13 | public class ServiceRegister { 14 | 15 | private String path; 16 | private Service data; 17 | private CreateMode mode;// 18 | 19 | public ServiceRegister() { 20 | } 21 | 22 | public ServiceRegister(String path, Object data,CreateMode mode) { 23 | super(); 24 | this.path = path; 25 | this.data = (Service) data; 26 | this.mode = mode; 27 | } 28 | 29 | @Override 30 | public int hashCode() { 31 | final int prime = 31; 32 | int result = 1; 33 | result = prime * result + ((path == null) ? 0 : path.hashCode()); 34 | return result; 35 | } 36 | 37 | // 当path 相同是 为同一个对象 38 | @Override 39 | public boolean equals(Object obj) { 40 | if (this == obj) 41 | return true; 42 | if (obj == null) 43 | return false; 44 | if (getClass() != obj.getClass()) 45 | return false; 46 | ServiceRegister other = (ServiceRegister) obj; 47 | if (path == null) { 48 | if (other.path != null) 49 | return false; 50 | } else if (!path.equals(other.path)) 51 | return false; 52 | return true; 53 | } 54 | 55 | public String getPath() { 56 | return path; 57 | } 58 | 59 | public void setPath(String path) { 60 | this.path = path; 61 | } 62 | 63 | public Service getData() { 64 | return data; 65 | } 66 | 67 | public void setData(Service data) { 68 | this.data = data; 69 | } 70 | 71 | public CreateMode getMode() { 72 | return mode; 73 | } 74 | 75 | public void setMode(CreateMode mode) { 76 | this.mode = mode; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/example/DomeServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.core.dispatcher.annotation.HandlerMsg; 4 | import com.core.netty.coder.Message; 5 | import com.google.protobuf.InvalidProtocolBufferException; 6 | import com.protobuf.Protobuf; 7 | import com.protobuf.Protobuf.TestData; 8 | 9 | public class DomeServerHandler { 10 | public static DomeServerHandler instance = new DomeServerHandler(); 11 | 12 | public static DomeServerHandler getInstance() { 13 | return instance; 14 | } 15 | private long start; 16 | private long end; 17 | 18 | @HandlerMsg(id = 10) 19 | public void test1(Message msg) { 20 | try { 21 | // Thread.sleep(10); 22 | TestData data = Protobuf.TestData.parseFrom(msg.getBody()); 23 | System.err.println(Thread.currentThread().getName()+" " +data.getId()+" " +msg.getSession().getChannel()); 24 | if(data.getId() ==1) { 25 | start =System.currentTimeMillis(); 26 | } 27 | if(data.getId() ==20000) { 28 | end =System.currentTimeMillis(); 29 | System.err.println("start:"+start); 30 | System.err.println("start:"+end); 31 | System.err.println("v:"+(end-start)); 32 | System.err.println(Thread.currentThread().getName()+" " +data.getId()); 33 | } 34 | 35 | } catch (Exception e) { 36 | e.printStackTrace(); 37 | } 38 | 39 | } 40 | 41 | @HandlerMsg(id = 11) 42 | public void test2(Message msg) { 43 | try { 44 | TestData data = Protobuf.TestData.parseFrom(msg.getBody()); 45 | System.err.println("消息11:"+data.getName()+" "+ msg.getSession().getChannel()); 46 | TestData.Builder db = TestData.newBuilder(); 47 | db.setName(data.getName()); 48 | msg.getSession().writeAndFlush(new Message((short)11, db.build().toByteArray())); 49 | } catch (InvalidProtocolBufferException e) { 50 | e.printStackTrace(); 51 | } 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/bootstrap/client/pool/TcpClientFactory.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.bootstrap.client.pool; 2 | 3 | import org.apache.commons.pool.BasePoolableObjectFactory; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import com.core.dispatcher.HandlerRegister; 8 | 9 | import io.netty.channel.Channel; 10 | import io.netty.channel.ChannelFuture; 11 | 12 | public class TcpClientFactory extends BasePoolableObjectFactory { 13 | protected Logger log = LoggerFactory.getLogger(this.getClass()); 14 | private SimpleTcpClient client; 15 | 16 | public TcpClientFactory(int port, String hosts,HandlerRegister register, boolean isReConn) { 17 | client = new SimpleTcpClient(hosts,port,register); 18 | } 19 | 20 | @Override 21 | public Object makeObject() throws Exception { 22 | ChannelFuture future = client.connect(); 23 | future.awaitUninterruptibly(); 24 | if (!future.isSuccess()) { 25 | log.error("Making new connection on " + client.getHosts() + client.getPort() + " not success", future.cause()); 26 | } 27 | TcpClientChannel channel = new TcpClientChannel(future); 28 | return channel; 29 | } 30 | 31 | @Override 32 | public void destroyObject(Object obj) throws Exception { 33 | if (obj instanceof TcpClientChannel) { 34 | TcpClientChannel c = (TcpClientChannel) obj; 35 | Channel channel = c.getChannelFuture().channel(); 36 | if (!channel.isOpen() || channel.isActive()) { 37 | channel.close(); 38 | } 39 | log.info("Closing channel and destroy connection from pool done"); 40 | } 41 | } 42 | 43 | @Override 44 | public boolean validateObject(Object obj) { 45 | if (obj instanceof TcpClientChannel) { 46 | final TcpClientChannel ch = (TcpClientChannel) obj; 47 | Channel channel = ch.getChannelFuture().channel(); 48 | return channel.isOpen() && channel.isActive(); 49 | } 50 | return false; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/dispatcher/MessageDispatcher.java: -------------------------------------------------------------------------------- 1 | package com.core.dispatcher; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.Map; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import com.core.dispatcher.annotation.HandlerMsg; 10 | import com.core.netty.coder.Message; 11 | import com.google.common.collect.Maps; 12 | 13 | /** 14 | * 消息注册与派发 15 | * 16 | * @Description: 17 | * @author: hang 18 | * @date: 2018年9月6日上午11:52:46 19 | * @version V1.7 20 | */ 21 | public class MessageDispatcher { 22 | protected static Logger log = LoggerFactory.getLogger(MessageDispatcher.class); 23 | 24 | private static Map methodMap = Maps.newConcurrentMap(); 25 | private static Map listenersMap = Maps.newConcurrentMap(); 26 | private static Map, Object> classMap = Maps.newConcurrentMap(); 27 | 28 | /** 29 | * 注册handler类 30 | * @param classz 31 | */ 32 | public static void register(Class classz) { 33 | try { 34 | if (classMap.containsKey(classz)) { 35 | return; 36 | } 37 | Object ben = classz.newInstance(); 38 | classMap.put(classz, ben); 39 | HandlerMsg listen; 40 | for (Method m : classz.getDeclaredMethods()) { 41 | if ((listen = m.getAnnotation(HandlerMsg.class)) != null) { 42 | int id = listen.id(); 43 | methodMap.put(id, m); 44 | listenersMap.put(m, ben); 45 | log.info("[register handler] msgId=[{}] method=[{}]", id, m.getName()); 46 | } 47 | } 48 | } catch (InstantiationException e) { 49 | throw new RuntimeException("MessageDispatcher register error", e); 50 | } catch (IllegalAccessException e) { 51 | throw new RuntimeException("MessageDispatcher register error", e); 52 | } 53 | 54 | } 55 | 56 | public static void dispatcher(Message msg) { 57 | try { 58 | int id = msg.getId(); 59 | Method method = methodMap.get(id); 60 | Object ben = listenersMap.get(method); 61 | method.invoke(ben, msg); 62 | } catch (Exception e) { 63 | log.error(" MessageDispatcher dispatcher error id=[{}]",msg.getId()); 64 | } 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/bootstrap/server/ServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.bootstrap.server; 2 | 3 | import java.util.concurrent.ConcurrentHashMap; 4 | 5 | import com.core.dispatcher.MessageDispatcher; 6 | import com.core.dispatcher.disruptor.DisruptorManager; 7 | import com.core.netty.coder.Message; 8 | import com.core.session.Session; 9 | 10 | import io.netty.channel.ChannelHandlerContext; 11 | import io.netty.channel.ChannelId; 12 | import io.netty.channel.SimpleChannelInboundHandler; 13 | 14 | public class ServerHandler extends SimpleChannelInboundHandler { 15 | 16 | public static final ConcurrentHashMap SESSIONS = new ConcurrentHashMap(); 17 | 18 | private static ThreadLocal LOCAL = new ThreadLocal() { 19 | @Override 20 | protected DisruptorManager initialValue() { 21 | return new DisruptorManager() { 22 | @Override 23 | public void eventHandler(Message msg, long sequence) { 24 | MessageDispatcher.dispatcher(msg); 25 | } 26 | }; 27 | } 28 | }; 29 | 30 | @Override 31 | protected void channelRead0(ChannelHandlerContext ctx, Message msg) throws Exception { 32 | Session session = SESSIONS.get(ctx.channel().id()); 33 | // System.err.println(ctx.channel().id().asLongText()); 34 | if(session!= null) { 35 | msg.setSession(session); 36 | LOCAL.get().publishEvent(msg); 37 | } 38 | 39 | } 40 | 41 | @Override 42 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 43 | // System.err.println(ctx.channel().id().asLongText()); 44 | // System.err.println(ctx.channel().id().asShortText()); 45 | // System.err.println(ctx.channel().isActive()); 46 | // System.err.println(ctx.channel().isOpen()); 47 | // System.err.println("是服务器"); 48 | Session session = new Session(ctx.channel()); 49 | SESSIONS.put(ctx.channel().id(), session); 50 | super.channelActive(ctx); 51 | } 52 | 53 | @Override 54 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 55 | SESSIONS.remove(ctx.channel().id()); 56 | super.channelInactive(ctx); 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/cluster/Service.java: -------------------------------------------------------------------------------- 1 | package com.core.cluster; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * 服务模型 7 | * 8 | * @Description: 9 | * @author: hang 10 | * @date: 2018年9月10日下午5:44:30 11 | * @version V1.7 12 | */ 13 | public class Service implements Serializable { 14 | private static final long serialVersionUID = 3946270881719849852L; 15 | 16 | private String serviceId;//服务的唯一id(业务自定义) 17 | private String hosts;//主机地址 18 | private int port;//主机端口号 19 | private int type;//服务类型(业务自定义) 20 | 21 | public Service() { 22 | } 23 | 24 | public Service(String id) { 25 | super(); 26 | this.serviceId = id; 27 | } 28 | 29 | public Service(String id,int type) { 30 | super(); 31 | this.serviceId = id; 32 | this.type = type; 33 | } 34 | 35 | 36 | public Service(String id, String hosts, int port, int type) { 37 | super(); 38 | this.serviceId = id; 39 | this.hosts = hosts; 40 | this.port = port; 41 | this.type = type; 42 | } 43 | 44 | 45 | 46 | @Override 47 | public String toString() { 48 | return "Service [id=" + serviceId + ", hosts=" + hosts + ", port=" + port + ", type=" + type + "]"; 49 | } 50 | 51 | @Override 52 | public int hashCode() { 53 | final int prime = 31; 54 | int result = 1; 55 | result = prime * result + ((serviceId == null) ? 0 : serviceId.hashCode()); 56 | return result; 57 | } 58 | 59 | @Override 60 | public boolean equals(Object obj) { 61 | if (this == obj) 62 | return true; 63 | if (obj == null) 64 | return false; 65 | if (getClass() != obj.getClass()) 66 | return false; 67 | Service other = (Service) obj; 68 | if (serviceId == null) { 69 | if (other.serviceId != null) 70 | return false; 71 | } else if (!serviceId.equals(other.serviceId)) 72 | return false; 73 | return true; 74 | } 75 | 76 | 77 | public String getServiceId() { 78 | return serviceId; 79 | } 80 | 81 | public void setServiceId(String serviceId) { 82 | this.serviceId = serviceId; 83 | } 84 | 85 | public String getHosts() { 86 | return hosts; 87 | } 88 | 89 | public void setHosts(String hosts) { 90 | this.hosts = hosts; 91 | } 92 | 93 | public int getPort() { 94 | return port; 95 | } 96 | 97 | public void setPort(int port) { 98 | this.port = port; 99 | } 100 | 101 | public int getType() { 102 | return type; 103 | } 104 | 105 | public void setType(int type) { 106 | this.type = type; 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/bootstrap/client/ReConnHandler.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.bootstrap.client; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | import io.netty.bootstrap.Bootstrap; 6 | import io.netty.channel.Channel; 7 | import io.netty.channel.ChannelFuture; 8 | import io.netty.channel.ChannelFutureListener; 9 | import io.netty.channel.ChannelHandler.Sharable; 10 | import io.netty.channel.ChannelHandlerContext; 11 | import io.netty.channel.ChannelInboundHandlerAdapter; 12 | import io.netty.channel.ChannelInitializer; 13 | import io.netty.util.HashedWheelTimer; 14 | import io.netty.util.Timeout; 15 | import io.netty.util.Timer; 16 | import io.netty.util.TimerTask; 17 | /** 18 | * 重连检测 19 | * @Description: 20 | * @author: hang 21 | * @date: 2018年9月3日下午5:44:05 22 | * @version V1.7 23 | */ 24 | @Sharable 25 | public abstract class ReConnHandler extends ChannelInboundHandlerAdapter implements TimerTask, HandlerHolder { 26 | 27 | private Bootstrap boot; 28 | private int renum;// 重连次数 29 | private boolean isReConn;// 是否重连 30 | private final Timer timer; 31 | private final int port; 32 | private final String host; 33 | private TcpClient tcpClient; 34 | 35 | public ReConnHandler(TcpClient tcpClient, String host, int port, boolean isReConn) { 36 | super(); 37 | this.tcpClient = tcpClient; 38 | this.boot = tcpClient.getBootstrap(); 39 | this.isReConn = isReConn; 40 | 41 | this.host = host; 42 | this.port = port; 43 | timer = new HashedWheelTimer(); 44 | } 45 | 46 | 47 | 48 | @Override 49 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 50 | // 注册 51 | renum = 0; 52 | ctx.fireChannelActive(); 53 | } 54 | 55 | @Override 56 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 57 | if (isReConn) { 58 | if (renum < 15) { 59 | renum++; 60 | long delay = renum; 61 | timer.newTimeout(this, delay, TimeUnit.SECONDS); 62 | } 63 | 64 | } 65 | ctx.fireChannelInactive(); 66 | 67 | } 68 | 69 | @Override 70 | public void run(Timeout timeout) throws Exception { 71 | ChannelFuture future; 72 | // bootstrap已经初始化好了,只需要将handler填入就可以了 73 | synchronized (boot) { 74 | boot.handler(new ChannelInitializer() { 75 | 76 | @Override 77 | protected void initChannel(Channel ch) throws Exception { 78 | 79 | ch.pipeline().addLast(handlers()); 80 | } 81 | }); 82 | future = boot.connect(host, port); 83 | } 84 | // future对象 85 | future.addListener(new ChannelFutureListener() { 86 | 87 | public void operationComplete(ChannelFuture f) throws Exception { 88 | boolean succeed = f.isSuccess(); 89 | // 如果重连失败,则调用ChannelInactive方法,再次出发重连事件,一直尝试12次,如果失败则不再重连 90 | if (!succeed) { 91 | System.out.println("重连失败"); 92 | f.channel().pipeline().fireChannelInactive(); 93 | } else { 94 | System.out.println("重连成功"); 95 | // System.out.println(future.channel()); 96 | tcpClient.setChannel(future.channel()); 97 | } 98 | } 99 | }); 100 | 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/bootstrap/server/TcpServer.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.bootstrap.server; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import com.core.netty.bootstrap.inter.IServer; 7 | import com.core.netty.coder.Decoder; 8 | import com.core.netty.coder.Encoder; 9 | 10 | import io.netty.bootstrap.ServerBootstrap; 11 | import io.netty.channel.Channel; 12 | import io.netty.channel.ChannelFuture; 13 | import io.netty.channel.ChannelFutureListener; 14 | import io.netty.channel.ChannelInitializer; 15 | import io.netty.channel.ChannelOption; 16 | import io.netty.channel.nio.NioEventLoopGroup; 17 | import io.netty.channel.socket.nio.NioServerSocketChannel; 18 | import io.netty.handler.timeout.IdleStateHandler; 19 | 20 | public abstract class TcpServer implements IServer { 21 | protected Logger log = LoggerFactory.getLogger(this.getClass()); 22 | private ServerBootstrap boot; 23 | private NioEventLoopGroup bossGroup; 24 | private NioEventLoopGroup workGroup; 25 | private int port; 26 | 27 | @Override 28 | public IServer listen(int port) { 29 | this.port = port; 30 | return this; 31 | } 32 | 33 | @Override 34 | public void start() { 35 | init(); 36 | boot = new ServerBootstrap(); 37 | bossGroup = new NioEventLoopGroup(); 38 | workGroup = new NioEventLoopGroup(); 39 | try { 40 | boot.group(bossGroup, workGroup).channel(NioServerSocketChannel.class) 41 | .option(ChannelOption.TCP_NODELAY, true) 42 | // .handler(new LoggingHandler(LogLevel.INFO)) 43 | .childHandler(new ChannelInitializer() { 44 | @Override 45 | protected void initChannel(Channel ch) throws Exception { 46 | ch.pipeline().addLast(new Decoder()); 47 | ch.pipeline().addLast(new Encoder()); 48 | ch.pipeline().addLast(new ServerHandler()); 49 | ch.pipeline().addLast(new IdleStateHandler(ServerIdleHandler.READER_TIME, 0, 0)); 50 | ch.pipeline().addLast(new ServerIdleHandler()); 51 | } 52 | }); 53 | ChannelFuture future = boot.bind(port).sync(); 54 | future.addListener(new ChannelFutureListener() { 55 | @Override 56 | public void operationComplete(ChannelFuture future) throws Exception { 57 | if (future.isSuccess()) { 58 | log.info("--------------------------------------------------------------------------------------"); 59 | log.info("--------------server Satrt----listenPort="+port+"-----------------------------------------"); 60 | log.info("--------------------------------------------------------------------------------------"); 61 | } 62 | } 63 | }); 64 | 65 | future.channel().closeFuture().sync(); 66 | } catch (InterruptedException e) { 67 | e.printStackTrace(); 68 | } finally { 69 | // add shutdown hook 70 | Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { 71 | @Override 72 | public void run() { 73 | stop(); 74 | } 75 | })); 76 | 77 | } 78 | 79 | } 80 | 81 | @Override 82 | public void stop() { 83 | if (bossGroup != null) { 84 | bossGroup.shutdownGracefully(); 85 | } 86 | if (workGroup != null) { 87 | workGroup.shutdownGracefully(); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/util/Pool.java: -------------------------------------------------------------------------------- 1 | package com.core.util; 2 | 3 | 4 | import org.apache.commons.pool.PoolableObjectFactory; 5 | import org.apache.commons.pool.impl.GenericObjectPool; 6 | 7 | 8 | /** 9 | * ClassName: Pool
10 | * Function: 封装commons-pool的抽象对象池 11 | * 12 | */ 13 | public abstract class Pool { 14 | 15 | /** 16 | * 对象池 17 | */ 18 | private final GenericObjectPool internalPool; 19 | 20 | /** 21 | * Creates a new instance of Pool. 22 | * 23 | * @param poolConfig 24 | * @param factory 25 | */ 26 | public Pool(final GenericObjectPool.Config poolConfig, PoolableObjectFactory factory) { 27 | this.internalPool = new GenericObjectPool(factory, poolConfig); 28 | } 29 | 30 | /** 31 | * 从对象池获取一个可用对象 32 | * 33 | * @return 34 | */ 35 | @SuppressWarnings("unchecked") 36 | public T getResource() { 37 | try { 38 | return (T) internalPool.borrowObject(); 39 | } catch (Exception e) { 40 | throw new RuntimeException("Could not get a resource from the pool", e); 41 | } 42 | } 43 | 44 | /** 45 | * 返回对象到池中 46 | * 47 | * @param resource 48 | */ 49 | public void returnResourceObject(final Object resource) { 50 | try { 51 | internalPool.returnObject(resource); 52 | } catch (Exception e) { 53 | throw new RuntimeException("Could not return the resource to the pool", e); 54 | } 55 | } 56 | 57 | /** 58 | * 返回一个调用失败的对象到池中 59 | * 60 | * @param resource 61 | */ 62 | public void returnBrokenResource(final T resource) { 63 | returnBrokenResourceObject(resource); 64 | } 65 | 66 | /** 67 | * 返回对象到池中 68 | * 69 | * @param resource 70 | */ 71 | public void returnResource(final T resource) { 72 | returnResourceObject(resource); 73 | } 74 | 75 | /** 76 | * 返回一个调用失败的对象到池中 77 | * 78 | * @param resource 79 | */ 80 | protected void returnBrokenResourceObject(final Object resource) { 81 | try { 82 | internalPool.invalidateObject(resource); 83 | } catch (Exception e) { 84 | throw new RuntimeException("Could not return the resource to the pool", e); 85 | } 86 | } 87 | 88 | /** 89 | * 获取活跃的池中对象数量 90 | * 91 | * @return 92 | */ 93 | public int getNumActive() { 94 | if (this.internalPool == null || this.internalPool.isClosed()) { 95 | return -1; 96 | } 97 | 98 | return this.internalPool.getNumActive(); 99 | } 100 | 101 | /** 102 | * 获取暂时idle的对象数量 103 | * 104 | * @return 105 | */ 106 | public int getNumIdle() { 107 | if (this.internalPool == null || this.internalPool.isClosed()) { 108 | return -1; 109 | } 110 | return internalPool.getNumIdle(); 111 | } 112 | 113 | /** 114 | * 销毁对象池 115 | */ 116 | public void destroy() { 117 | try { 118 | internalPool.close(); 119 | } catch (Exception e) { 120 | throw new RuntimeException("Could not destroy the pool", e); 121 | } 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /fast-netty/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | com.qihang 5 | fast-netty 6 | 1.0 7 | 8 | 1.8 9 | UTF-8 10 | 11 | 12 | 13 | 14 | io.netty 15 | netty-all 16 | 4.1.42.Final 17 | 18 | 19 | 20 | com.google.protobuf 21 | protobuf-java 22 | 2.5.0 23 | 24 | 25 | junit 26 | junit 27 | 4.8.2 28 | test 29 | 30 | 31 | 32 | com.lmax 33 | disruptor 34 | 3.3.6 35 | 36 | 37 | 38 | 39 | org.slf4j 40 | slf4j-api 41 | 1.7.10 42 | 43 | 44 | ch.qos.logback 45 | logback-core 46 | 1.1.2 47 | 48 | 49 | ch.qos.logback 50 | logback-classic 51 | 1.1.2 52 | 53 | 54 | ch.qos.logback 55 | logback-access 56 | 1.1.2 57 | 58 | 59 | 60 | commons-pool 61 | commons-pool 62 | 1.5.7 63 | 64 | 65 | 66 | 67 | org.apache.zookeeper 68 | zookeeper 69 | 3.4.14 70 | 71 | 72 | com.101tec 73 | zkclient 74 | 0.4 75 | 76 | 77 | 78 | com.google.guava 79 | guava 80 | 18.0 81 | 82 | 83 | 84 | 85 | 86 | 87 | org.apache.maven.plugins 88 | maven-compiler-plugin 89 | 90 | ${java.version} 91 | ${java.version} 92 | 93 | 94 | 95 | 96 | org.apache.maven.plugins 97 | maven-dependency-plugin 98 | 99 | 100 | 101 | copy-dependencies 102 | package 103 | 104 | copy-dependencies 105 | 106 | 107 | ${project.build.directory}/lib 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/bootstrap/client/TcpClient.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.bootstrap.client; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import com.core.dispatcher.HandlerRegister; 7 | import com.core.netty.bootstrap.inter.IClient; 8 | import com.core.netty.coder.Decoder; 9 | import com.core.netty.coder.Encoder; 10 | import io.netty.bootstrap.Bootstrap; 11 | import io.netty.channel.Channel; 12 | import io.netty.channel.ChannelFuture; 13 | import io.netty.channel.ChannelFutureListener; 14 | import io.netty.channel.ChannelHandler; 15 | import io.netty.channel.ChannelInitializer; 16 | import io.netty.channel.ChannelOption; 17 | import io.netty.channel.nio.NioEventLoopGroup; 18 | import io.netty.channel.socket.SocketChannel; 19 | import io.netty.channel.socket.nio.NioSocketChannel; 20 | 21 | public abstract class TcpClient implements IClient { 22 | protected Logger log = LoggerFactory.getLogger(this.getClass()); 23 | private Channel channel; 24 | private Bootstrap bootstrap; 25 | private NioEventLoopGroup workGroup; 26 | protected HandlerRegister register;// 注册的handlers 27 | private int port;//主机端口 28 | private String hosts;//主机地址 29 | private boolean isReConn;// 重连 30 | 31 | public TcpClient(String hosts, int port) { 32 | this(hosts,port,false); 33 | } 34 | public TcpClient(String hosts, int port,boolean isReConn) { 35 | this.hosts = hosts; 36 | this.port = port; 37 | this.isReConn = isReConn; 38 | init(); 39 | bootstrap = new Bootstrap(); 40 | workGroup = new NioEventLoopGroup(); 41 | bootstrap.group(workGroup); 42 | bootstrap.channel(NioSocketChannel.class); 43 | bootstrap.option(ChannelOption.SO_KEEPALIVE, true); 44 | // 重连检测handler 45 | ReConnHandler reConnHandler = new ReConnHandler(this, this.hosts,this.port, this.isReConn) { 46 | 47 | @Override 48 | public ChannelHandler[] handlers() { 49 | return new ChannelHandler[] { this, new Decoder(), new Encoder(), new ClientHandler() }; 50 | } 51 | }; 52 | bootstrap.handler(new ChannelInitializer() { 53 | @Override 54 | public void initChannel(SocketChannel ch) throws Exception { 55 | ch.pipeline().addLast(reConnHandler.handlers()); 56 | } 57 | }); 58 | } 59 | 60 | 61 | @Override 62 | public void start() { 63 | 64 | } 65 | 66 | @Override 67 | public void stop() { 68 | if (workGroup != null) { 69 | workGroup.shutdownGracefully(); 70 | } 71 | } 72 | 73 | /** 74 | * 连接 75 | * 76 | * @return 77 | */ 78 | public ChannelFuture connect() { 79 | try { 80 | ChannelFuture future = bootstrap.connect(this.hosts, this.port); 81 | this.channel = future.channel(); 82 | future.addListener(new ChannelFutureListener() { 83 | @Override 84 | public void operationComplete(ChannelFuture channelFuture) throws Exception { 85 | if (channelFuture.isSuccess()) { 86 | log.info("Connection " + channelFuture.channel() + " is well established"); 87 | } else { 88 | log.warn(String.format("Connection get failed on %s due to %s", 89 | channelFuture.cause().getMessage(), channelFuture.cause())); 90 | } 91 | } 92 | }); 93 | return future; 94 | 95 | } catch (Exception e) { 96 | log.error("Failed to connect to " + this.hosts + this.port + " due to " + e.getMessage(), e); 97 | throw new RuntimeException(e); 98 | } 99 | } 100 | 101 | @Override 102 | public void writeAndFlush(Object msg) { 103 | if (channel != null) { 104 | if (channel.isActive()) { 105 | channel.writeAndFlush(msg); 106 | } 107 | } 108 | } 109 | 110 | 111 | public Channel getChannel() { 112 | return channel; 113 | } 114 | 115 | public void setChannel(Channel channel) { 116 | this.channel = channel; 117 | } 118 | 119 | public Bootstrap getBootstrap() { 120 | return bootstrap; 121 | } 122 | 123 | public void setBootstrap(Bootstrap bootstrap) { 124 | this.bootstrap = bootstrap; 125 | } 126 | 127 | public int getPort() { 128 | return port; 129 | } 130 | 131 | public void setPort(int port) { 132 | this.port = port; 133 | } 134 | 135 | public String getHosts() { 136 | return hosts; 137 | } 138 | 139 | public void setHosts(String hosts) { 140 | this.hosts = hosts; 141 | } 142 | 143 | 144 | } 145 | -------------------------------------------------------------------------------- /fast-netty/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{} %msg %n 9 | 10 | 11 | 15 | 16 | 17 | 18 | 19 | 21 | logs/error.log 22 | 23 | 24 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{} %msg %n 25 | 26 | 27 | 28 | ERROR 29 | ACCEPT 30 | DENY 31 | 32 | 33 | 34 | 35 | logs/error-%d{yyyy-MM-dd}.%i.log 36 | 20 37 | 39 | 40 | 100MB 41 | 42 | 43 | 44 | 45 | 46 | 48 | logs/warn.log 49 | 50 | 51 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{} %msg %n 52 | 53 | 54 | 55 | WARN 56 | ACCEPT 57 | DENY 58 | 59 | 60 | 61 | 62 | logs/warn-%d{yyyy-MM-dd}.%i.log 63 | 20 64 | 66 | 67 | 100MB 68 | 69 | 70 | 71 | 72 | 73 | 75 | logs/info.log 76 | 77 | 78 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{} %msg %n 79 | 80 | 81 | 82 | INFO 83 | ACCEPT 84 | DENY 85 | 86 | 87 | 88 | 89 | logs/info-%d{yyyy-MM-dd}.%i.log 90 | 20 91 | 93 | 94 | 100MB 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 104 | logs/debug.log 105 | 106 | 107 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{} %msg %n 108 | 109 | 110 | 111 | DEBUG 112 | ACCEPT 113 | DENY 114 | 115 | 116 | 117 | 118 | logs/debug-%d{yyyy-MM-dd}.%i.log 119 | 20 120 | 122 | 123 | 100MB 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/cluster/ClusterDispatcher.java: -------------------------------------------------------------------------------- 1 | package com.core.cluster; 2 | 3 | import java.util.Map; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import com.core.cluster.strategy.Strategy; 9 | import com.core.netty.bootstrap.client.pool.PooledClient; 10 | import com.core.netty.bootstrap.inter.IClient; 11 | import com.core.netty.coder.Message; 12 | import com.google.common.collect.Maps; 13 | import com.google.protobuf.GeneratedMessage; 14 | 15 | /** 16 | * 集群消息分发器 17 | * 18 | * @Description: 19 | * @author: hang 20 | * @date: 2018年9月11日下午4:07:00 21 | * @version V1.7 22 | */ 23 | public class ClusterDispatcher { 24 | protected Logger log = LoggerFactory.getLogger(this.getClass()); 25 | // 服务信息 连接池客户端 26 | private static Map pooledClientMap = Maps.newConcurrentMap(); 27 | // key 唯一标识 value 服务 28 | private static Map serviceMap = Maps.newConcurrentMap(); 29 | 30 | private ClusterManager clusterManager;// 服务管理者 31 | 32 | /** 33 | * 34 | * @param address 35 | * zk地址 36 | */ 37 | public ClusterDispatcher(String address) { 38 | this.clusterManager = new ClusterManager(address); 39 | } 40 | 41 | /** 42 | * 43 | * @param address 44 | * zkserver 地址 45 | * @param strategy 46 | * 发现策略 47 | */ 48 | public ClusterDispatcher(String address, Strategy strategy) { 49 | this.clusterManager = new ClusterManager(address, strategy); 50 | } 51 | 52 | /** 53 | * 策略发现服务 发送消息 ( 第一次调用绑定 uuid 与 服务的连接, 后 续发送不需再次发现) 54 | * @param uuid 55 | * @param serviceType 56 | * @param msgId 57 | * @param msg 58 | */ 59 | public void sendFirstMsgByDiscovery(String uuid, int serviceType, short msgId, GeneratedMessage msg) { 60 | Message message = new Message(msgId, msg.toByteArray()); 61 | try { 62 | IClient clientPool = getClientByDiscovery(uuid, serviceType); 63 | if (clientPool != null) { 64 | clientPool.writeAndFlush(message); 65 | } 66 | 67 | } catch (Exception e) { 68 | log.error("sendFirstDiscoveryMsg",e); 69 | } 70 | } 71 | 72 | 73 | /** 74 | * 指定发现服务 发送消息 ( 第一次调用绑定 uuid 与 服务的连接, 后 续发送不需再次发现) 75 | * @param uuid 76 | * @param serviceType 77 | * @param msgId 78 | * @param msg 79 | */ 80 | public void sendFirstMsgByServiceId(String uuid, int serviceType, String serviceId, short msgId, GeneratedMessage msg) { 81 | Message message = new Message(msgId, msg.toByteArray()); 82 | try { 83 | IClient clientPool = getClientByServiceId(uuid, serviceType, serviceId); 84 | if (clientPool != null) { 85 | clientPool.writeAndFlush(message); 86 | } 87 | 88 | } catch (Exception e) { 89 | log.error("sendFirstMsgByServiceId",e); 90 | } 91 | } 92 | 93 | /** 94 | * 根据uuid 找到 服务 发送消息 在第一次发现后 后续用这个方法发送消息(之前已经绑定过无需发现) 95 | * @param uuid 96 | * @param serviceType 97 | * @param msgId 98 | * @param msg 99 | */ 100 | public void sendMsg(String uuid, int serviceType, short msgId, byte[] msg) { 101 | Message message = new Message(msgId, msg); 102 | try { 103 | IClient clientPool = getClient(uuid, serviceType); 104 | if (clientPool != null) { 105 | clientPool.writeAndFlush(message); 106 | } 107 | 108 | } catch (Exception e) { 109 | log.error("sendMsg",e); 110 | } 111 | } 112 | 113 | /** 114 | * 根据uuid 找到 服务 发送消息 在第一次发现后 后续用这个方法发送消息(之前已经绑定过无需发现) 115 | * @param uuid 116 | * @param serviceType 117 | * @param msgId 118 | * @param msg 119 | */ 120 | public void sendMsg(String uuid, int serviceType, short msgId, GeneratedMessage msg) { 121 | sendMsg(uuid, serviceType,msgId,msg.toByteArray()); 122 | } 123 | 124 | 125 | 126 | /** 127 | * 根据服务ID 发现服务 128 | * 129 | * @param uuid 130 | * @param serviceType 131 | * @param serviceId 132 | * @return 133 | */ 134 | public IClient getClientByServiceId(String uuid, int serviceType, String serviceId) { 135 | 136 | String uuidKey = uuid + "-type-" + serviceType; 137 | if (serviceId != null) { 138 | // 根据服务ID 发现服务 139 | // 去发现服务 140 | Service service = clusterManager.serviceDiscovery(serviceType, serviceId); 141 | // System.err.println(service); 142 | if (service == null) { 143 | throw new RuntimeException("no service is Discovery"); 144 | } 145 | 146 | if (!pooledClientMap.containsKey(service)) { 147 | IClient clientPool2 = new PooledClient(service.getHosts(), service.getPort()); 148 | pooledClientMap.put(service, clientPool2); 149 | } 150 | serviceMap.put(uuidKey, service); 151 | // System.err.println(" 11 " + service); 152 | } 153 | return getClient(uuid,serviceType); 154 | 155 | } 156 | 157 | /** 158 | * 根据次略发现服务 159 | * 160 | * @param uuid 161 | * @param serviceType 162 | * @param isDiscovery 163 | * @return 164 | */ 165 | public IClient getClientByDiscovery(String uuid, int serviceType) { 166 | String uuidKey = uuid + "-type-" + serviceType; 167 | // 发现服务 168 | Service service = clusterManager.serviceDiscovery(serviceType); 169 | // System.err.println(service); 170 | if (service == null) { 171 | throw new RuntimeException("no service is Discovery"); 172 | } 173 | 174 | if (!pooledClientMap.containsKey(service)) { 175 | IClient clientPool2 = new PooledClient(service.getHosts(), service.getPort()); 176 | pooledClientMap.put(service, clientPool2); 177 | } 178 | serviceMap.put(uuidKey, service); 179 | // System.err.println(" 22 " + service); 180 | return getClient(uuid,serviceType); 181 | } 182 | 183 | public IClient getClient(String uuid, int serviceType) { 184 | IClient clientPool = null; 185 | String uuidKey = uuid + "-type-" + serviceType; 186 | try { 187 | if (!serviceMap.containsKey(uuidKey)) { 188 | log.error("no service "); 189 | return clientPool; 190 | } 191 | Service service = serviceMap.get(uuidKey); 192 | clientPool = pooledClientMap.get(service); 193 | // System.err.println(" 33 " + service); 194 | 195 | } catch (Exception e) { 196 | log.error("ClusterHolder clientPool writeAndFlush ", e); 197 | } 198 | return clientPool; 199 | } 200 | 201 | public ClusterManager getClusterManager() { 202 | return clusterManager; 203 | } 204 | 205 | public void setClusterManager(ClusterManager clusterManager) { 206 | this.clusterManager = clusterManager; 207 | } 208 | 209 | public void registerService(String path, Object data) { 210 | this.clusterManager.registerService(path, data); 211 | } 212 | 213 | public static void main(String[] args) { 214 | 215 | } 216 | 217 | } 218 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/cluster/ClusterManager.java: -------------------------------------------------------------------------------- 1 | package com.core.cluster; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | import java.util.Set; 6 | import java.util.concurrent.locks.Lock; 7 | import java.util.concurrent.locks.ReentrantLock; 8 | 9 | import org.I0Itec.zkclient.IZkChildListener; 10 | import org.I0Itec.zkclient.IZkStateListener; 11 | import org.I0Itec.zkclient.ZkClient; 12 | import org.apache.zookeeper.CreateMode; 13 | import org.apache.zookeeper.Watcher.Event.KeeperState; 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | 17 | import com.core.cluster.strategy.OrderLoopStrategy; 18 | import com.core.cluster.strategy.Strategy; 19 | import com.google.common.collect.Maps; 20 | import com.google.common.collect.Sets; 21 | 22 | /** 23 | * 集群服务管理 24 | * 25 | * @Description: 26 | * @author: hang 27 | * @date: 2018年9月10日下午5:23:16 28 | * @version V1.7 29 | */ 30 | public class ClusterManager { 31 | protected Logger log = LoggerFactory.getLogger(this.getClass()); 32 | public int SESSION_TIME_OUT = 100; 33 | 34 | public ZkClient zkClient;//zk客户端 35 | public Strategy strategy;// 服务发现策略 36 | public Lock lock = new ReentrantLock(); 37 | 38 | public static String ROOT_PATH = "/service";// 服务注册根路径 39 | 40 | //已发现的服务资源 41 | public static Map> services = Maps.newConcurrentMap(); 42 | // 本实例 注册的服务缓存 断线重连后 重新注册 43 | public static Set registeredServices = Sets.newConcurrentHashSet(); 44 | 45 | /** 46 | * 47 | * @param address zk服务器地址 48 | * address= "192.168.31.150:3001";//单台配置 49 | * address="192.168.31.150:3001,192.168.31.150:3002,192.168.31.150:3003";多台集群 50 | * @param strategy 服务发现策略 目前 有随机 还有轮训 可自由定义实现{@link Strategy} 51 | */ 52 | public ClusterManager(String address,Strategy strategy) { 53 | this.strategy = strategy; 54 | zkClient = new ZkClient(address, SESSION_TIME_OUT, Integer.MAX_VALUE); 55 | zkClient.subscribeStateChanges(new HAStateListener()); 56 | } 57 | public ClusterManager(String address) { 58 | this(address,new OrderLoopStrategy());//默认轮训策略 59 | } 60 | 61 | 62 | /** 63 | * 创建集群配置信息 64 | * 65 | * @param path 66 | * @param data 67 | * @param mode 68 | */ 69 | public void createPath(String path, Object data, CreateMode mode) { 70 | if (!zkClient.exists(path)) { 71 | zkClient.create(path, data, mode); 72 | } else { 73 | zkClient.writeData(path, data); 74 | } 75 | registeredServices.add(new ServiceRegister(path, data, mode)); 76 | } 77 | 78 | /** 79 | * 断线重连 重新注册服务 80 | */ 81 | public void reRegister() { 82 | if (!registeredServices.isEmpty()) { 83 | for (ServiceRegister s : registeredServices) { 84 | createPath(s.getPath(), s.getData(), s.getMode()); 85 | } 86 | } 87 | } 88 | 89 | /** 90 | * 注册服务 91 | * 92 | * @param path 93 | * @param data 94 | * @param mode 95 | */ 96 | public void registerService(String path, Object data) { 97 | try { 98 | if (!zkClient.exists(ROOT_PATH)) { 99 | createPath(ROOT_PATH, null, CreateMode.PERSISTENT); 100 | } 101 | path = ROOT_PATH + "/" + path; 102 | this.createPath(path, data, CreateMode.EPHEMERAL); 103 | } catch (Exception e) { 104 | throw new RuntimeException("registerService",e); 105 | } 106 | 107 | } 108 | /** 109 | * 服务发现 110 | * 111 | 112 | * @param serviceType 113 | * 114 | * @return 115 | */ 116 | public Service serviceDiscovery(int serviceType) { 117 | return serviceDiscovery(serviceType,null); 118 | } 119 | 120 | /** 121 | * 服务发现 122 | * @param serviceType 服务类型 123 | * @param serviceId 服务id 124 | * @return 125 | */ 126 | public Service serviceDiscovery(int serviceType,String serviceId) { 127 | if (services.isEmpty() || services.get(serviceType) == null || services.get(serviceType).isEmpty()) { 128 | if (zkClient.exists(ROOT_PATH)) { 129 | servicesInit(); 130 | // 监听child改变 131 | zkClient.subscribeChildChanges(ROOT_PATH, new HAChildListener()); 132 | } 133 | } 134 | if (!services.isEmpty()&&services.get(serviceType) != null && !services.get(serviceType).isEmpty()) { 135 | if(serviceId == null) { 136 | return strategy.discovery(services.get(serviceType)); 137 | }else { 138 | Set set= services.get(serviceType); 139 | if(!set.isEmpty()) { 140 | for(Service service : set) { 141 | if(service.getServiceId().equals(serviceId)){ 142 | return service; 143 | } 144 | } 145 | } 146 | } 147 | 148 | } 149 | return null; 150 | } 151 | 152 | public void servicesInit() { 153 | try { 154 | lock.lock(); 155 | services.clear(); 156 | List childs = zkClient.getChildren(ROOT_PATH); 157 | if (childs != null && !childs.isEmpty()) { 158 | for (String childPath : childs) { 159 | Service service = zkClient.readData(ROOT_PATH + "/" + childPath); 160 | if (!services.containsKey(service.getType())) { 161 | services.put(service.getType(), Sets.newConcurrentHashSet()); 162 | } 163 | services.get(service.getType()).add(service); 164 | } 165 | log.info("services init Childs=[{}]",childs); 166 | } 167 | } finally { 168 | lock.unlock(); 169 | } 170 | 171 | } 172 | 173 | public ZkClient getZkClient() { 174 | return zkClient; 175 | } 176 | 177 | public void setZkClient(ZkClient zkClient) { 178 | this.zkClient = zkClient; 179 | } 180 | 181 | // 状态监听 182 | class HAStateListener implements IZkStateListener { 183 | 184 | @Override 185 | public void handleStateChanged(KeeperState state) throws Exception { 186 | 187 | if (state == KeeperState.Disconnected) { 188 | log.warn("Disconnected connection to the zkServer "); 189 | //services.clear();//zkServer 断开 暂不清理缓存的服务 190 | } else if (state == KeeperState.SyncConnected) { 191 | // 重新连接zk服务器 重新注册缓存信息 192 | reRegister(); 193 | log.warn("reConnection to the zkServer reRegister"); 194 | } 195 | 196 | } 197 | 198 | @Override 199 | public void handleNewSession() throws Exception { 200 | 201 | } 202 | 203 | @Override 204 | public void handleSessionEstablishmentError(Throwable error) throws Exception { 205 | 206 | } 207 | 208 | } 209 | 210 | class HAChildListener implements IZkChildListener { 211 | 212 | @Override 213 | public void handleChildChange(String parentPath, List currentChilds) throws Exception { 214 | log.info("listener handleChildChange parentPath=[{}] Childs=[{}]",parentPath,currentChilds); 215 | if(parentPath.equals(ROOT_PATH)) { 216 | servicesInit(); 217 | } 218 | } 219 | } 220 | 221 | public static void main(String[] args) throws InterruptedException { 222 | // HACluster ha = new HACluster("127.0.0.1:2100"); 223 | ClusterManager ha = new ClusterManager("127.0.0.1:2100",new OrderLoopStrategy()); 224 | 225 | ha.registerService("s1",new Service("s1id",1)); 226 | ha.registerService("s2", new Service("s2id",1)); 227 | ha.registerService("s3", new Service("s3id",1)); 228 | ha.registerService("s4", new Service("s4id",1)); 229 | ha.registerService("s5", new Service("s5id",1)); 230 | for(int i=0;i<10;i++) { 231 | Object o1= ha.serviceDiscovery(1); 232 | System.err.println("main="+o1); 233 | } 234 | 235 | while(true) { 236 | Thread.sleep(2000l); 237 | Object o1= ha.serviceDiscovery(1); 238 | System.err.println("main="+o1); 239 | } 240 | 241 | } 242 | 243 | } 244 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/core/netty/bootstrap/client/pool/PooledConfig.java: -------------------------------------------------------------------------------- 1 | package com.core.netty.bootstrap.client.pool; 2 | 3 | import org.apache.commons.pool.impl.GenericObjectPool; 4 | /** 5 | * 连接池配置 6 | * @Description: 7 | * @author: hang 8 | * @date: 2018年9月7日下午2:09:15 9 | * @version V1.7 10 | */ 11 | public class PooledConfig { 12 | /** 13 | * 控制池中空闲的对象的最大数量。 默认值是8,如果是负值表示没限制。 14 | */ 15 | private int maxIdle = GenericObjectPool.DEFAULT_MAX_IDLE; 16 | 17 | /** 18 | * whenExhaustedAction如果是WHEN_EXHAUSTED_BLOCK,指定等待的毫秒数。
19 | * 如果maxWait是正数,那么会等待maxWait的毫秒的时间,超时会抛出NoSuchElementException异常 ;
20 | * 如果maxWait为负值,会永久等待。 maxWait的默认值是-1。 21 | */ 22 | private long maxWait = GenericObjectPool.DEFAULT_MAX_WAIT; 23 | 24 | /** 25 | * 如果testOnBorrow被设置,pool会在borrowObject返回对象之前使用PoolableObjectFactory的validateObject来验证这个对象是否有效,要是对象没通过验证,这个对象会被丢弃, 26 | * 然后重新选择一个新的对象。 testOnBorrow的默认值是false,可以使用GenericObjectPool.DEFAULT_TEST_ON_BORROW;。 27 | *

28 | * 注意,对于长期idle的连接,服务端会默认关闭channel此时客户端并不知晓,因此不能使用已经失效的channel,为保证客户端可用,这里暂时使用这个策略每次borrow的时候都test 29 | */ 30 | private boolean testOnBorrow = true; 31 | 32 | /** 33 | * 控制池中空闲的对象的最小数量。 默认值是0。 34 | */ 35 | private int minIdle = GenericObjectPool.DEFAULT_MIN_IDLE; 36 | 37 | /** 38 | * 控制池中对象的最大数量。 默认值是8,如果是负值表示没限制。 39 | */ 40 | private int maxActive = GenericObjectPool.DEFAULT_MAX_ACTIVE; 41 | 42 | /** 43 | * 如果testOnReturn被设置,pool会在returnObject的时候通过PoolableObjectFactory的validateObject方法验证对象,如果对象没通过验证,对象会被丢弃,不会被放到池中。 44 | * testOnReturn的默认值是false。 45 | */ 46 | private boolean testOnReturn = GenericObjectPool.DEFAULT_TEST_ON_RETURN; 47 | 48 | /** 49 | * 指定idle对象是否应该使用PoolableObjectFactory的validateObject校验,如果校验失败,这个对象会从对象池中被清除。 50 | * 这个设置仅在timeBetweenEvictionRunsMillis被设置成正值(>0)的时候才会生效。 testWhileIdle的默认值是false。 51 | */ 52 | private boolean testWhileIdle = GenericObjectPool.DEFAULT_TEST_WHILE_IDLE; 53 | 54 | /** 55 | * 指定驱逐线程的休眠时间。如果这个值不是正数(>0),不会有驱逐线程运行。 timeBetweenEvictionRunsMillis的默认值是-1。 56 | */ 57 | private long timeBetweenEvictionRunsMillis = GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS; 58 | 59 | /** 60 | * 设置驱逐线程每次检测对象的数量。 这个设置仅在timeBetweenEvictionRunsMillis被设置成正值(>0)的时候才会生效。 numTestsPerEvictionRun的默认值是3。 61 | */ 62 | private int numTestsPerEvictionRun = GenericObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN; 63 | 64 | /** 65 | * 指定最小的空闲驱逐的时间间隔(空闲超过指定的时间的对象,会被清除掉)。 这个设置仅在timeBetweenEvictionRunsMillis被设置成正值(>0)的时候才会生效。 66 | * minEvictableIdleTimeMillis默认值是30分钟。 67 | */ 68 | private long minEvictableIdleTimeMillis = GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS; 69 | 70 | /** 71 | * 与minEvictableIdleTimeMillis类似,也是指定最小的空闲驱逐的时间间隔(空闲超过指定的时间的对象,会被清除掉),不过会参考minIdle的值,只有idle对象的数量超过minIdle的值,对象才会被清除。 72 | * 这个设置仅在timeBetweenEvictionRunsMillis被设置成正值 73 | * (>0)的时候才会生效,并且这个配置能被minEvictableIdleTimeMillis配置取代(minEvictableIdleTimeMillis配置项的优先级更高)。 74 | * softMinEvictableIdleTimeMillis的默认值是-1。 75 | */ 76 | private long softMinEvictableIdleTimeMillis = GenericObjectPool.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS; 77 | 78 | /** 79 | * 设置后进先出的池策略。pool可以被配置成LIFO队列(last-in-first-out)或FIFO队列(first-in-first-out),来指定空闲对象被使用的次序。 lifo的默认值是true。 80 | */ 81 | private boolean lifo = GenericObjectPool.DEFAULT_LIFO; 82 | 83 | /** 84 | * 指定池中对象被消耗完以后的行为,有下面这些选择: WHEN_EXHAUSTED_FAIL 0 WHEN_EXHAUSTED_GROW 2 WHEN_EXHAUSTED_BLOCK 1 85 | * 如果是WHEN_EXHAUSTED_FAIL,当池中对象达到上限以后,继续borrowObject会抛出NoSuchElementException异常。 86 | * 如果是WHEN_EXHAUSTED_GROW,当池中对象达到上限以后,会创建一个新对象,并返回它。 87 | * 如果是WHEN_EXHAUSTED_BLOCK,当池中对象达到上限以后,会一直等待,直到有一个对象可用。这个行为还与maxWait有关 88 | * ,如果maxWait是正数,那么会等待maxWait的毫秒的时间,超时会抛出NoSuchElementException异常;如果maxWait为负值,会永久等待。 89 | * whenExhaustedAction的默认值是WHEN_EXHAUSTED_BLOCK,maxWait的默认值是-1。 90 | */ 91 | private byte whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK; 92 | 93 | /** 94 | * 获取对象池配置 95 | * 96 | * @return 97 | */ 98 | public GenericObjectPool.Config getPoolConfig() { 99 | GenericObjectPool.Config poolConfig = new GenericObjectPool.Config(); 100 | // maxIdle为负数时,不对pool size大小做限制,此处做限制,防止保持过多空闲redis连接 101 | if (this.maxIdle >= 0) { 102 | poolConfig.maxIdle = this.maxIdle; 103 | } 104 | poolConfig.maxWait = this.maxWait; 105 | if (this.whenExhaustedAction >= 0 && this.whenExhaustedAction < 3) { 106 | poolConfig.whenExhaustedAction = this.whenExhaustedAction; 107 | } 108 | poolConfig.testOnBorrow = this.testOnBorrow; 109 | poolConfig.minIdle = this.minIdle; 110 | poolConfig.maxActive = this.maxActive; 111 | poolConfig.testOnReturn = this.testOnReturn; 112 | poolConfig.testWhileIdle = this.testWhileIdle; 113 | poolConfig.timeBetweenEvictionRunsMillis = this.timeBetweenEvictionRunsMillis; 114 | poolConfig.numTestsPerEvictionRun = this.numTestsPerEvictionRun; 115 | poolConfig.minEvictableIdleTimeMillis = this.minEvictableIdleTimeMillis; 116 | poolConfig.softMinEvictableIdleTimeMillis = this.softMinEvictableIdleTimeMillis; 117 | poolConfig.lifo = this.lifo; 118 | return poolConfig; 119 | } 120 | 121 | public int getMaxIdle() { 122 | return maxIdle; 123 | } 124 | 125 | public void setMaxIdle(int maxIdle) { 126 | this.maxIdle = maxIdle; 127 | } 128 | 129 | public long getMaxWait() { 130 | return maxWait; 131 | } 132 | 133 | public void setMaxWait(long maxWait) { 134 | this.maxWait = maxWait; 135 | } 136 | 137 | public boolean isTestOnBorrow() { 138 | return testOnBorrow; 139 | } 140 | 141 | public void setTestOnBorrow(boolean testOnBorrow) { 142 | this.testOnBorrow = testOnBorrow; 143 | } 144 | 145 | public int getMinIdle() { 146 | return minIdle; 147 | } 148 | 149 | public void setMinIdle(int minIdle) { 150 | this.minIdle = minIdle; 151 | } 152 | 153 | public int getMaxActive() { 154 | return maxActive; 155 | } 156 | 157 | public void setMaxActive(int maxActive) { 158 | this.maxActive = maxActive; 159 | } 160 | 161 | public boolean isTestOnReturn() { 162 | return testOnReturn; 163 | } 164 | 165 | public void setTestOnReturn(boolean testOnReturn) { 166 | this.testOnReturn = testOnReturn; 167 | } 168 | 169 | public boolean isTestWhileIdle() { 170 | return testWhileIdle; 171 | } 172 | 173 | public void setTestWhileIdle(boolean testWhileIdle) { 174 | this.testWhileIdle = testWhileIdle; 175 | } 176 | 177 | public long getTimeBetweenEvictionRunsMillis() { 178 | return timeBetweenEvictionRunsMillis; 179 | } 180 | 181 | public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) { 182 | this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; 183 | } 184 | 185 | public int getNumTestsPerEvictionRun() { 186 | return numTestsPerEvictionRun; 187 | } 188 | 189 | public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) { 190 | this.numTestsPerEvictionRun = numTestsPerEvictionRun; 191 | } 192 | 193 | public long getMinEvictableIdleTimeMillis() { 194 | return minEvictableIdleTimeMillis; 195 | } 196 | 197 | public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) { 198 | this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; 199 | } 200 | 201 | public long getSoftMinEvictableIdleTimeMillis() { 202 | return softMinEvictableIdleTimeMillis; 203 | } 204 | 205 | public void setSoftMinEvictableIdleTimeMillis(long softMinEvictableIdleTimeMillis) { 206 | this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis; 207 | } 208 | 209 | public boolean isLifo() { 210 | return lifo; 211 | } 212 | 213 | public void setLifo(boolean lifo) { 214 | this.lifo = lifo; 215 | } 216 | 217 | public byte getWhenExhaustedAction() { 218 | return whenExhaustedAction; 219 | } 220 | 221 | public void setWhenExhaustedAction(byte whenExhaustedAction) { 222 | this.whenExhaustedAction = whenExhaustedAction; 223 | } 224 | 225 | } 226 | -------------------------------------------------------------------------------- /fast-netty/src/main/java/com/protobuf/Protobuf.java: -------------------------------------------------------------------------------- 1 | // Generated by the protocol buffer compiler. DO NOT EDIT! 2 | // source: Protobuf.proto 3 | 4 | package com.protobuf; 5 | 6 | public final class Protobuf { 7 | private Protobuf() {} 8 | public static void registerAllExtensions( 9 | com.google.protobuf.ExtensionRegistry registry) { 10 | } 11 | public interface TestDataOrBuilder 12 | extends com.google.protobuf.MessageOrBuilder { 13 | 14 | // optional int32 age = 1; 15 | /** 16 | * optional int32 age = 1; 17 | */ 18 | boolean hasAge(); 19 | /** 20 | * optional int32 age = 1; 21 | */ 22 | int getAge(); 23 | 24 | // optional string name = 2; 25 | /** 26 | * optional string name = 2; 27 | */ 28 | boolean hasName(); 29 | /** 30 | * optional string name = 2; 31 | */ 32 | java.lang.String getName(); 33 | /** 34 | * optional string name = 2; 35 | */ 36 | com.google.protobuf.ByteString 37 | getNameBytes(); 38 | 39 | // optional int32 id = 3; 40 | /** 41 | * optional int32 id = 3; 42 | */ 43 | boolean hasId(); 44 | /** 45 | * optional int32 id = 3; 46 | */ 47 | int getId(); 48 | } 49 | /** 50 | * Protobuf type {@code dough.protocol.TestData} 51 | */ 52 | public static final class TestData extends 53 | com.google.protobuf.GeneratedMessage 54 | implements TestDataOrBuilder { 55 | // Use TestData.newBuilder() to construct. 56 | private TestData(com.google.protobuf.GeneratedMessage.Builder builder) { 57 | super(builder); 58 | this.unknownFields = builder.getUnknownFields(); 59 | } 60 | private TestData(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } 61 | 62 | private static final TestData defaultInstance; 63 | public static TestData getDefaultInstance() { 64 | return defaultInstance; 65 | } 66 | 67 | public TestData getDefaultInstanceForType() { 68 | return defaultInstance; 69 | } 70 | 71 | private final com.google.protobuf.UnknownFieldSet unknownFields; 72 | @java.lang.Override 73 | public final com.google.protobuf.UnknownFieldSet 74 | getUnknownFields() { 75 | return this.unknownFields; 76 | } 77 | private TestData( 78 | com.google.protobuf.CodedInputStream input, 79 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 80 | throws com.google.protobuf.InvalidProtocolBufferException { 81 | initFields(); 82 | int mutable_bitField0_ = 0; 83 | com.google.protobuf.UnknownFieldSet.Builder unknownFields = 84 | com.google.protobuf.UnknownFieldSet.newBuilder(); 85 | try { 86 | boolean done = false; 87 | while (!done) { 88 | int tag = input.readTag(); 89 | switch (tag) { 90 | case 0: 91 | done = true; 92 | break; 93 | default: { 94 | if (!parseUnknownField(input, unknownFields, 95 | extensionRegistry, tag)) { 96 | done = true; 97 | } 98 | break; 99 | } 100 | case 8: { 101 | bitField0_ |= 0x00000001; 102 | age_ = input.readInt32(); 103 | break; 104 | } 105 | case 18: { 106 | bitField0_ |= 0x00000002; 107 | name_ = input.readBytes(); 108 | break; 109 | } 110 | case 24: { 111 | bitField0_ |= 0x00000004; 112 | id_ = input.readInt32(); 113 | break; 114 | } 115 | } 116 | } 117 | } catch (com.google.protobuf.InvalidProtocolBufferException e) { 118 | throw e.setUnfinishedMessage(this); 119 | } catch (java.io.IOException e) { 120 | throw new com.google.protobuf.InvalidProtocolBufferException( 121 | e.getMessage()).setUnfinishedMessage(this); 122 | } finally { 123 | this.unknownFields = unknownFields.build(); 124 | makeExtensionsImmutable(); 125 | } 126 | } 127 | public static final com.google.protobuf.Descriptors.Descriptor 128 | getDescriptor() { 129 | return com.protobuf.Protobuf.internal_static_dough_protocol_TestData_descriptor; 130 | } 131 | 132 | protected com.google.protobuf.GeneratedMessage.FieldAccessorTable 133 | internalGetFieldAccessorTable() { 134 | return com.protobuf.Protobuf.internal_static_dough_protocol_TestData_fieldAccessorTable 135 | .ensureFieldAccessorsInitialized( 136 | com.protobuf.Protobuf.TestData.class, com.protobuf.Protobuf.TestData.Builder.class); 137 | } 138 | 139 | public static com.google.protobuf.Parser PARSER = 140 | new com.google.protobuf.AbstractParser() { 141 | public TestData parsePartialFrom( 142 | com.google.protobuf.CodedInputStream input, 143 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 144 | throws com.google.protobuf.InvalidProtocolBufferException { 145 | return new TestData(input, extensionRegistry); 146 | } 147 | }; 148 | 149 | @java.lang.Override 150 | public com.google.protobuf.Parser getParserForType() { 151 | return PARSER; 152 | } 153 | 154 | private int bitField0_; 155 | // optional int32 age = 1; 156 | public static final int AGE_FIELD_NUMBER = 1; 157 | private int age_; 158 | /** 159 | * optional int32 age = 1; 160 | */ 161 | public boolean hasAge() { 162 | return ((bitField0_ & 0x00000001) == 0x00000001); 163 | } 164 | /** 165 | * optional int32 age = 1; 166 | */ 167 | public int getAge() { 168 | return age_; 169 | } 170 | 171 | // optional string name = 2; 172 | public static final int NAME_FIELD_NUMBER = 2; 173 | private java.lang.Object name_; 174 | /** 175 | * optional string name = 2; 176 | */ 177 | public boolean hasName() { 178 | return ((bitField0_ & 0x00000002) == 0x00000002); 179 | } 180 | /** 181 | * optional string name = 2; 182 | */ 183 | public java.lang.String getName() { 184 | java.lang.Object ref = name_; 185 | if (ref instanceof java.lang.String) { 186 | return (java.lang.String) ref; 187 | } else { 188 | com.google.protobuf.ByteString bs = 189 | (com.google.protobuf.ByteString) ref; 190 | java.lang.String s = bs.toStringUtf8(); 191 | if (bs.isValidUtf8()) { 192 | name_ = s; 193 | } 194 | return s; 195 | } 196 | } 197 | /** 198 | * optional string name = 2; 199 | */ 200 | public com.google.protobuf.ByteString 201 | getNameBytes() { 202 | java.lang.Object ref = name_; 203 | if (ref instanceof java.lang.String) { 204 | com.google.protobuf.ByteString b = 205 | com.google.protobuf.ByteString.copyFromUtf8( 206 | (java.lang.String) ref); 207 | name_ = b; 208 | return b; 209 | } else { 210 | return (com.google.protobuf.ByteString) ref; 211 | } 212 | } 213 | 214 | // optional int32 id = 3; 215 | public static final int ID_FIELD_NUMBER = 3; 216 | private int id_; 217 | /** 218 | * optional int32 id = 3; 219 | */ 220 | public boolean hasId() { 221 | return ((bitField0_ & 0x00000004) == 0x00000004); 222 | } 223 | /** 224 | * optional int32 id = 3; 225 | */ 226 | public int getId() { 227 | return id_; 228 | } 229 | 230 | private void initFields() { 231 | age_ = 0; 232 | name_ = ""; 233 | id_ = 0; 234 | } 235 | private byte memoizedIsInitialized = -1; 236 | public final boolean isInitialized() { 237 | byte isInitialized = memoizedIsInitialized; 238 | if (isInitialized != -1) return isInitialized == 1; 239 | 240 | memoizedIsInitialized = 1; 241 | return true; 242 | } 243 | 244 | public void writeTo(com.google.protobuf.CodedOutputStream output) 245 | throws java.io.IOException { 246 | getSerializedSize(); 247 | if (((bitField0_ & 0x00000001) == 0x00000001)) { 248 | output.writeInt32(1, age_); 249 | } 250 | if (((bitField0_ & 0x00000002) == 0x00000002)) { 251 | output.writeBytes(2, getNameBytes()); 252 | } 253 | if (((bitField0_ & 0x00000004) == 0x00000004)) { 254 | output.writeInt32(3, id_); 255 | } 256 | getUnknownFields().writeTo(output); 257 | } 258 | 259 | private int memoizedSerializedSize = -1; 260 | public int getSerializedSize() { 261 | int size = memoizedSerializedSize; 262 | if (size != -1) return size; 263 | 264 | size = 0; 265 | if (((bitField0_ & 0x00000001) == 0x00000001)) { 266 | size += com.google.protobuf.CodedOutputStream 267 | .computeInt32Size(1, age_); 268 | } 269 | if (((bitField0_ & 0x00000002) == 0x00000002)) { 270 | size += com.google.protobuf.CodedOutputStream 271 | .computeBytesSize(2, getNameBytes()); 272 | } 273 | if (((bitField0_ & 0x00000004) == 0x00000004)) { 274 | size += com.google.protobuf.CodedOutputStream 275 | .computeInt32Size(3, id_); 276 | } 277 | size += getUnknownFields().getSerializedSize(); 278 | memoizedSerializedSize = size; 279 | return size; 280 | } 281 | 282 | private static final long serialVersionUID = 0L; 283 | @java.lang.Override 284 | protected java.lang.Object writeReplace() 285 | throws java.io.ObjectStreamException { 286 | return super.writeReplace(); 287 | } 288 | 289 | public static com.protobuf.Protobuf.TestData parseFrom( 290 | com.google.protobuf.ByteString data) 291 | throws com.google.protobuf.InvalidProtocolBufferException { 292 | return PARSER.parseFrom(data); 293 | } 294 | public static com.protobuf.Protobuf.TestData parseFrom( 295 | com.google.protobuf.ByteString data, 296 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 297 | throws com.google.protobuf.InvalidProtocolBufferException { 298 | return PARSER.parseFrom(data, extensionRegistry); 299 | } 300 | public static com.protobuf.Protobuf.TestData parseFrom(byte[] data) 301 | throws com.google.protobuf.InvalidProtocolBufferException { 302 | return PARSER.parseFrom(data); 303 | } 304 | public static com.protobuf.Protobuf.TestData parseFrom( 305 | byte[] data, 306 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 307 | throws com.google.protobuf.InvalidProtocolBufferException { 308 | return PARSER.parseFrom(data, extensionRegistry); 309 | } 310 | public static com.protobuf.Protobuf.TestData parseFrom(java.io.InputStream input) 311 | throws java.io.IOException { 312 | return PARSER.parseFrom(input); 313 | } 314 | public static com.protobuf.Protobuf.TestData parseFrom( 315 | java.io.InputStream input, 316 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 317 | throws java.io.IOException { 318 | return PARSER.parseFrom(input, extensionRegistry); 319 | } 320 | public static com.protobuf.Protobuf.TestData parseDelimitedFrom(java.io.InputStream input) 321 | throws java.io.IOException { 322 | return PARSER.parseDelimitedFrom(input); 323 | } 324 | public static com.protobuf.Protobuf.TestData parseDelimitedFrom( 325 | java.io.InputStream input, 326 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 327 | throws java.io.IOException { 328 | return PARSER.parseDelimitedFrom(input, extensionRegistry); 329 | } 330 | public static com.protobuf.Protobuf.TestData parseFrom( 331 | com.google.protobuf.CodedInputStream input) 332 | throws java.io.IOException { 333 | return PARSER.parseFrom(input); 334 | } 335 | public static com.protobuf.Protobuf.TestData parseFrom( 336 | com.google.protobuf.CodedInputStream input, 337 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 338 | throws java.io.IOException { 339 | return PARSER.parseFrom(input, extensionRegistry); 340 | } 341 | 342 | public static Builder newBuilder() { return Builder.create(); } 343 | public Builder newBuilderForType() { return newBuilder(); } 344 | public static Builder newBuilder(com.protobuf.Protobuf.TestData prototype) { 345 | return newBuilder().mergeFrom(prototype); 346 | } 347 | public Builder toBuilder() { return newBuilder(this); } 348 | 349 | @java.lang.Override 350 | protected Builder newBuilderForType( 351 | com.google.protobuf.GeneratedMessage.BuilderParent parent) { 352 | Builder builder = new Builder(parent); 353 | return builder; 354 | } 355 | /** 356 | * Protobuf type {@code dough.protocol.TestData} 357 | */ 358 | public static final class Builder extends 359 | com.google.protobuf.GeneratedMessage.Builder 360 | implements com.protobuf.Protobuf.TestDataOrBuilder { 361 | public static final com.google.protobuf.Descriptors.Descriptor 362 | getDescriptor() { 363 | return com.protobuf.Protobuf.internal_static_dough_protocol_TestData_descriptor; 364 | } 365 | 366 | protected com.google.protobuf.GeneratedMessage.FieldAccessorTable 367 | internalGetFieldAccessorTable() { 368 | return com.protobuf.Protobuf.internal_static_dough_protocol_TestData_fieldAccessorTable 369 | .ensureFieldAccessorsInitialized( 370 | com.protobuf.Protobuf.TestData.class, com.protobuf.Protobuf.TestData.Builder.class); 371 | } 372 | 373 | // Construct using com.protobuf.Protobuf.TestData.newBuilder() 374 | private Builder() { 375 | maybeForceBuilderInitialization(); 376 | } 377 | 378 | private Builder( 379 | com.google.protobuf.GeneratedMessage.BuilderParent parent) { 380 | super(parent); 381 | maybeForceBuilderInitialization(); 382 | } 383 | private void maybeForceBuilderInitialization() { 384 | if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { 385 | } 386 | } 387 | private static Builder create() { 388 | return new Builder(); 389 | } 390 | 391 | public Builder clear() { 392 | super.clear(); 393 | age_ = 0; 394 | bitField0_ = (bitField0_ & ~0x00000001); 395 | name_ = ""; 396 | bitField0_ = (bitField0_ & ~0x00000002); 397 | id_ = 0; 398 | bitField0_ = (bitField0_ & ~0x00000004); 399 | return this; 400 | } 401 | 402 | public Builder clone() { 403 | return create().mergeFrom(buildPartial()); 404 | } 405 | 406 | public com.google.protobuf.Descriptors.Descriptor 407 | getDescriptorForType() { 408 | return com.protobuf.Protobuf.internal_static_dough_protocol_TestData_descriptor; 409 | } 410 | 411 | public com.protobuf.Protobuf.TestData getDefaultInstanceForType() { 412 | return com.protobuf.Protobuf.TestData.getDefaultInstance(); 413 | } 414 | 415 | public com.protobuf.Protobuf.TestData build() { 416 | com.protobuf.Protobuf.TestData result = buildPartial(); 417 | if (!result.isInitialized()) { 418 | throw newUninitializedMessageException(result); 419 | } 420 | return result; 421 | } 422 | 423 | public com.protobuf.Protobuf.TestData buildPartial() { 424 | com.protobuf.Protobuf.TestData result = new com.protobuf.Protobuf.TestData(this); 425 | int from_bitField0_ = bitField0_; 426 | int to_bitField0_ = 0; 427 | if (((from_bitField0_ & 0x00000001) == 0x00000001)) { 428 | to_bitField0_ |= 0x00000001; 429 | } 430 | result.age_ = age_; 431 | if (((from_bitField0_ & 0x00000002) == 0x00000002)) { 432 | to_bitField0_ |= 0x00000002; 433 | } 434 | result.name_ = name_; 435 | if (((from_bitField0_ & 0x00000004) == 0x00000004)) { 436 | to_bitField0_ |= 0x00000004; 437 | } 438 | result.id_ = id_; 439 | result.bitField0_ = to_bitField0_; 440 | onBuilt(); 441 | return result; 442 | } 443 | 444 | public Builder mergeFrom(com.google.protobuf.Message other) { 445 | if (other instanceof com.protobuf.Protobuf.TestData) { 446 | return mergeFrom((com.protobuf.Protobuf.TestData)other); 447 | } else { 448 | super.mergeFrom(other); 449 | return this; 450 | } 451 | } 452 | 453 | public Builder mergeFrom(com.protobuf.Protobuf.TestData other) { 454 | if (other == com.protobuf.Protobuf.TestData.getDefaultInstance()) return this; 455 | if (other.hasAge()) { 456 | setAge(other.getAge()); 457 | } 458 | if (other.hasName()) { 459 | bitField0_ |= 0x00000002; 460 | name_ = other.name_; 461 | onChanged(); 462 | } 463 | if (other.hasId()) { 464 | setId(other.getId()); 465 | } 466 | this.mergeUnknownFields(other.getUnknownFields()); 467 | return this; 468 | } 469 | 470 | public final boolean isInitialized() { 471 | return true; 472 | } 473 | 474 | public Builder mergeFrom( 475 | com.google.protobuf.CodedInputStream input, 476 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 477 | throws java.io.IOException { 478 | com.protobuf.Protobuf.TestData parsedMessage = null; 479 | try { 480 | parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); 481 | } catch (com.google.protobuf.InvalidProtocolBufferException e) { 482 | parsedMessage = (com.protobuf.Protobuf.TestData) e.getUnfinishedMessage(); 483 | throw e; 484 | } finally { 485 | if (parsedMessage != null) { 486 | mergeFrom(parsedMessage); 487 | } 488 | } 489 | return this; 490 | } 491 | private int bitField0_; 492 | 493 | // optional int32 age = 1; 494 | private int age_ ; 495 | /** 496 | * optional int32 age = 1; 497 | */ 498 | public boolean hasAge() { 499 | return ((bitField0_ & 0x00000001) == 0x00000001); 500 | } 501 | /** 502 | * optional int32 age = 1; 503 | */ 504 | public int getAge() { 505 | return age_; 506 | } 507 | /** 508 | * optional int32 age = 1; 509 | */ 510 | public Builder setAge(int value) { 511 | bitField0_ |= 0x00000001; 512 | age_ = value; 513 | onChanged(); 514 | return this; 515 | } 516 | /** 517 | * optional int32 age = 1; 518 | */ 519 | public Builder clearAge() { 520 | bitField0_ = (bitField0_ & ~0x00000001); 521 | age_ = 0; 522 | onChanged(); 523 | return this; 524 | } 525 | 526 | // optional string name = 2; 527 | private java.lang.Object name_ = ""; 528 | /** 529 | * optional string name = 2; 530 | */ 531 | public boolean hasName() { 532 | return ((bitField0_ & 0x00000002) == 0x00000002); 533 | } 534 | /** 535 | * optional string name = 2; 536 | */ 537 | public java.lang.String getName() { 538 | java.lang.Object ref = name_; 539 | if (!(ref instanceof java.lang.String)) { 540 | java.lang.String s = ((com.google.protobuf.ByteString) ref) 541 | .toStringUtf8(); 542 | name_ = s; 543 | return s; 544 | } else { 545 | return (java.lang.String) ref; 546 | } 547 | } 548 | /** 549 | * optional string name = 2; 550 | */ 551 | public com.google.protobuf.ByteString 552 | getNameBytes() { 553 | java.lang.Object ref = name_; 554 | if (ref instanceof String) { 555 | com.google.protobuf.ByteString b = 556 | com.google.protobuf.ByteString.copyFromUtf8( 557 | (java.lang.String) ref); 558 | name_ = b; 559 | return b; 560 | } else { 561 | return (com.google.protobuf.ByteString) ref; 562 | } 563 | } 564 | /** 565 | * optional string name = 2; 566 | */ 567 | public Builder setName( 568 | java.lang.String value) { 569 | if (value == null) { 570 | throw new NullPointerException(); 571 | } 572 | bitField0_ |= 0x00000002; 573 | name_ = value; 574 | onChanged(); 575 | return this; 576 | } 577 | /** 578 | * optional string name = 2; 579 | */ 580 | public Builder clearName() { 581 | bitField0_ = (bitField0_ & ~0x00000002); 582 | name_ = getDefaultInstance().getName(); 583 | onChanged(); 584 | return this; 585 | } 586 | /** 587 | * optional string name = 2; 588 | */ 589 | public Builder setNameBytes( 590 | com.google.protobuf.ByteString value) { 591 | if (value == null) { 592 | throw new NullPointerException(); 593 | } 594 | bitField0_ |= 0x00000002; 595 | name_ = value; 596 | onChanged(); 597 | return this; 598 | } 599 | 600 | // optional int32 id = 3; 601 | private int id_ ; 602 | /** 603 | * optional int32 id = 3; 604 | */ 605 | public boolean hasId() { 606 | return ((bitField0_ & 0x00000004) == 0x00000004); 607 | } 608 | /** 609 | * optional int32 id = 3; 610 | */ 611 | public int getId() { 612 | return id_; 613 | } 614 | /** 615 | * optional int32 id = 3; 616 | */ 617 | public Builder setId(int value) { 618 | bitField0_ |= 0x00000004; 619 | id_ = value; 620 | onChanged(); 621 | return this; 622 | } 623 | /** 624 | * optional int32 id = 3; 625 | */ 626 | public Builder clearId() { 627 | bitField0_ = (bitField0_ & ~0x00000004); 628 | id_ = 0; 629 | onChanged(); 630 | return this; 631 | } 632 | 633 | // @@protoc_insertion_point(builder_scope:dough.protocol.TestData) 634 | } 635 | 636 | static { 637 | defaultInstance = new TestData(true); 638 | defaultInstance.initFields(); 639 | } 640 | 641 | // @@protoc_insertion_point(class_scope:dough.protocol.TestData) 642 | } 643 | 644 | private static com.google.protobuf.Descriptors.Descriptor 645 | internal_static_dough_protocol_TestData_descriptor; 646 | private static 647 | com.google.protobuf.GeneratedMessage.FieldAccessorTable 648 | internal_static_dough_protocol_TestData_fieldAccessorTable; 649 | 650 | public static com.google.protobuf.Descriptors.FileDescriptor 651 | getDescriptor() { 652 | return descriptor; 653 | } 654 | private static com.google.protobuf.Descriptors.FileDescriptor 655 | descriptor; 656 | static { 657 | java.lang.String[] descriptorData = { 658 | "\n\016Protobuf.proto\022\016dough.protocol\"1\n\010Test" + 659 | "Data\022\013\n\003age\030\001 \001(\005\022\014\n\004name\030\002 \001(\t\022\n\n\002id\030\003 " + 660 | "\001(\005B\016\n\014com.protobuf" 661 | }; 662 | com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = 663 | new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { 664 | public com.google.protobuf.ExtensionRegistry assignDescriptors( 665 | com.google.protobuf.Descriptors.FileDescriptor root) { 666 | descriptor = root; 667 | internal_static_dough_protocol_TestData_descriptor = 668 | getDescriptor().getMessageTypes().get(0); 669 | internal_static_dough_protocol_TestData_fieldAccessorTable = new 670 | com.google.protobuf.GeneratedMessage.FieldAccessorTable( 671 | internal_static_dough_protocol_TestData_descriptor, 672 | new java.lang.String[] { "Age", "Name", "Id", }); 673 | return null; 674 | } 675 | }; 676 | com.google.protobuf.Descriptors.FileDescriptor 677 | .internalBuildGeneratedFileFrom(descriptorData, 678 | new com.google.protobuf.Descriptors.FileDescriptor[] { 679 | }, assigner); 680 | } 681 | 682 | // @@protoc_insertion_point(outer_class_scope) 683 | } 684 | --------------------------------------------------------------------------------