├── .DS_Store ├── .classpath ├── .gitignore ├── .project ├── .settings ├── com.google.eclipse.protobuf.Protobuf.prefs ├── org.eclipse.core.resources.prefs ├── org.eclipse.jdt.core.prefs ├── org.eclipse.ltk.core.refactoring.prefs ├── org.eclipse.m2e.core.prefs └── org.eclipse.wst.common.project.facet.core.xml ├── README.md ├── pom.xml └── src ├── .DS_Store ├── main ├── .DS_Store ├── java │ ├── .DS_Store │ └── com │ │ ├── .DS_Store │ │ └── netty │ │ ├── .DS_Store │ │ ├── client │ │ ├── NettyClient.java │ │ └── handler │ │ │ ├── IdleClientHandler.java │ │ │ └── LogicClientHandler.java │ │ ├── common │ │ ├── protobuf │ │ │ ├── Command.java │ │ │ ├── Command.proto │ │ │ ├── Message.java │ │ │ └── Message.proto │ │ └── util │ │ │ └── ReflectionUtil.java │ │ └── server │ │ ├── Application.java │ │ ├── ChannelRepository.java │ │ ├── ServerChannelInitializer.java │ │ ├── TCPServer.java │ │ └── handler │ │ ├── AuthServerHandler.java │ │ ├── IdleServerHandler.java │ │ └── LogicServerHandler.java └── resources │ └── application.properties └── test ├── .DS_Store └── java └── .DS_Store /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nosqlcoco/springboot-netty-protobuf/5615a426f519adacd6b86ecb2eb0953ffb53fad1/.DS_Store -------------------------------------------------------------------------------- /.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 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /src-gen/ -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | springboot-netty-protobuf 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.xtext.ui.shared.xtextBuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.wst.common.project.facet.core.builder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.m2e.core.maven2Builder 25 | 26 | 27 | 28 | 29 | 30 | org.eclipse.jdt.core.javanature 31 | org.eclipse.m2e.core.maven2Nature 32 | org.eclipse.wst.common.project.facet.core.nature 33 | org.eclipse.xtext.ui.shared.xtextNature 34 | 35 | 36 | -------------------------------------------------------------------------------- /.settings/com.google.eclipse.protobuf.Protobuf.prefs: -------------------------------------------------------------------------------- 1 | compiler.descriptorFilePath=D\:\\devtools\\protobuf\\include\\google\\protobuf\\descriptor.proto 2 | compiler.enableProjectSettings=true 3 | compiler.protocFilePath=D\:\\devtools\\protobuf\\bin\\protoc.exe 4 | compiler.refreshOutputDirectory=true 5 | compiler.refreshProject=false 6 | eclipse.preferences.version=1 7 | paths.directoryPaths=${workspace_loc\:/${project}/src/main/java/com/netty/common/protobuf} 8 | paths.filesInMultipleDirectories=true 9 | paths.filesInOneDirectoryOnly=false 10 | -------------------------------------------------------------------------------- /.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//src/test/java=UTF-8 5 | encoding/=UTF-8 6 | -------------------------------------------------------------------------------- /.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.methodParameters=do not generate 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=1.8 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 13 | org.eclipse.jdt.core.compiler.source=1.8 14 | -------------------------------------------------------------------------------- /.settings/org.eclipse.ltk.core.refactoring.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false 3 | -------------------------------------------------------------------------------- /.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.common.project.facet.core.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # springboot-netty-protobuf 2 | 3 | #### 一、说明 4 | springboot集成netty,使用protobuf作为数据交换格式,可以用于智能终端云端服务脚手架。 5 | 6 | - 已完成功能(2017/03/12) 7 | 1. 接入验证 8 | - 心跳检测 9 | - 断开重连 10 | - 上传数据 11 | - 主动推送功能 12 | - 待完成 13 | 1. SSL验证 14 | - 上传文件 15 | 16 | #### 二、开发环境 17 | - JDK8+ 18 | - Eclipse Neon.2 Release 19 | - springboot1.4.2 20 | - Netty4.1.6.Final 21 | - protobuf-java3.0.0 22 | 23 | 24 | #### 三、使用方法 25 | 项目里面包含Socket客户端和服务端 26 | - 找到com.netty.server.Application类右键debug as启动SocketServer 27 | - 找到com.netty.client.NettyClient类右键debug as启动客户端 28 | 29 | PS:我的公众号: 30 | 31 | ![](https://github.com/cocoli/weixin_smallexe/blob/master/screenshot/dingyuhao.JPG?raw=true) 32 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.netty 7 | netty-dmeo 8 | 1.0.0 9 | jar 10 | 11 | springboot-netty-protobuf Demo 12 | springboot集成netty,使用protobuf作为数据传输格式,包含心跳检测、断开重连、上传数据、主动推送功能 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.4.2.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | 1.8 24 | 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter 29 | 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-test 34 | test 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-aop 39 | 40 | 41 | 42 | io.netty 43 | netty-all 44 | 4.1.6.Final 45 | 46 | 47 | com.google.protobuf 48 | protobuf-java 49 | 3.0.0 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-maven-plugin 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nosqlcoco/springboot-netty-protobuf/5615a426f519adacd6b86ecb2eb0953ffb53fad1/src/.DS_Store -------------------------------------------------------------------------------- /src/main/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nosqlcoco/springboot-netty-protobuf/5615a426f519adacd6b86ecb2eb0953ffb53fad1/src/main/.DS_Store -------------------------------------------------------------------------------- /src/main/java/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nosqlcoco/springboot-netty-protobuf/5615a426f519adacd6b86ecb2eb0953ffb53fad1/src/main/java/.DS_Store -------------------------------------------------------------------------------- /src/main/java/com/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nosqlcoco/springboot-netty-protobuf/5615a426f519adacd6b86ecb2eb0953ffb53fad1/src/main/java/com/.DS_Store -------------------------------------------------------------------------------- /src/main/java/com/netty/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nosqlcoco/springboot-netty-protobuf/5615a426f519adacd6b86ecb2eb0953ffb53fad1/src/main/java/com/netty/.DS_Store -------------------------------------------------------------------------------- /src/main/java/com/netty/client/NettyClient.java: -------------------------------------------------------------------------------- 1 | package com.netty.client; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | import org.apache.log4j.Logger; 6 | 7 | import com.netty.client.handler.IdleClientHandler; 8 | import com.netty.client.handler.LogicClientHandler; 9 | import com.netty.common.protobuf.Message.MessageBase; 10 | 11 | import io.netty.bootstrap.Bootstrap; 12 | import io.netty.channel.ChannelFuture; 13 | import io.netty.channel.ChannelInitializer; 14 | import io.netty.channel.ChannelOption; 15 | import io.netty.channel.ChannelPipeline; 16 | import io.netty.channel.EventLoop; 17 | import io.netty.channel.EventLoopGroup; 18 | import io.netty.channel.nio.NioEventLoopGroup; 19 | import io.netty.channel.socket.SocketChannel; 20 | import io.netty.channel.socket.nio.NioSocketChannel; 21 | import io.netty.handler.codec.protobuf.ProtobufDecoder; 22 | import io.netty.handler.codec.protobuf.ProtobufEncoder; 23 | import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; 24 | import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender; 25 | import io.netty.handler.timeout.IdleStateHandler; 26 | /** 27 | * netty客户端 28 | * @author lenovo 29 | * 30 | */ 31 | public class NettyClient { 32 | public Logger log = Logger.getLogger(this.getClass()); 33 | 34 | private final static String HOST = "127.0.0.1"; 35 | private final static int PORT = 8090; 36 | private final static int READER_IDLE_TIME_SECONDS = 20;//读操作空闲20秒 37 | private final static int WRITER_IDLE_TIME_SECONDS = 20;//写操作空闲20秒 38 | private final static int ALL_IDLE_TIME_SECONDS = 40;//读写全部空闲40秒 39 | 40 | private EventLoopGroup loop = new NioEventLoopGroup(); 41 | 42 | public static void main(String[] args) throws Exception { 43 | NettyClient client = new NettyClient(); 44 | client.run(); 45 | } 46 | 47 | public void run() throws Exception { 48 | try { 49 | doConnect(new Bootstrap(), loop); 50 | }catch (Exception e) { 51 | e.printStackTrace(); 52 | } 53 | } 54 | 55 | /** 56 | * netty client 连接,连接失败10秒后重试连接 57 | */ 58 | public Bootstrap doConnect(Bootstrap bootstrap, EventLoopGroup eventLoopGroup) { 59 | try { 60 | if (bootstrap != null) { 61 | bootstrap.group(eventLoopGroup); 62 | bootstrap.channel(NioSocketChannel.class); 63 | bootstrap.option(ChannelOption.SO_KEEPALIVE, true); 64 | bootstrap.handler(new ChannelInitializer() { 65 | @Override 66 | public void initChannel(SocketChannel ch) throws Exception { 67 | ChannelPipeline p = ch.pipeline(); 68 | 69 | p.addLast("idleStateHandler", new IdleStateHandler(READER_IDLE_TIME_SECONDS 70 | , WRITER_IDLE_TIME_SECONDS, ALL_IDLE_TIME_SECONDS, TimeUnit.SECONDS)); 71 | p.addLast("idleTimeoutHandler", new IdleClientHandler(NettyClient.this)); 72 | 73 | p.addLast(new ProtobufVarint32FrameDecoder()); 74 | p.addLast(new ProtobufDecoder(MessageBase.getDefaultInstance())); 75 | 76 | p.addLast(new ProtobufVarint32LengthFieldPrepender()); 77 | p.addLast(new ProtobufEncoder()); 78 | 79 | p.addLast("clientHandler", new LogicClientHandler()); 80 | } 81 | }); 82 | bootstrap.remoteAddress(HOST, PORT); 83 | ChannelFuture f = bootstrap.connect().addListener((ChannelFuture futureListener)->{ 84 | final EventLoop eventLoop = futureListener.channel().eventLoop(); 85 | if (!futureListener.isSuccess()) { 86 | log.warn("Failed to connect to server, try connect after 10s"); 87 | futureListener.channel().eventLoop().schedule(() -> doConnect(new Bootstrap(), eventLoop), 10, TimeUnit.SECONDS); 88 | } 89 | }); 90 | f.channel().closeFuture().sync(); 91 | eventLoopGroup.shutdownGracefully(); 92 | } 93 | } catch (InterruptedException e) { 94 | e.printStackTrace(); 95 | } 96 | return bootstrap; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/com/netty/client/handler/IdleClientHandler.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.handler; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | import org.apache.log4j.Logger; 6 | 7 | import com.netty.common.protobuf.Message; 8 | import com.netty.client.NettyClient; 9 | import com.netty.common.protobuf.Command.CommandType; 10 | import com.netty.common.protobuf.Message.MessageBase; 11 | 12 | import io.netty.bootstrap.Bootstrap; 13 | import io.netty.channel.ChannelHandlerContext; 14 | import io.netty.channel.EventLoop; 15 | import io.netty.channel.SimpleChannelInboundHandler; 16 | import io.netty.handler.timeout.IdleState; 17 | import io.netty.handler.timeout.IdleStateEvent; 18 | 19 | public class IdleClientHandler extends SimpleChannelInboundHandler { 20 | public Logger log = Logger.getLogger(this.getClass()); 21 | 22 | private NettyClient nettyClient; 23 | private int heartbeatCount = 0; 24 | private final static String CLIENTID = "123456789"; 25 | 26 | /** 27 | * @param nettyClient 28 | */ 29 | public IdleClientHandler(NettyClient nettyClient) { 30 | this.nettyClient = nettyClient; 31 | } 32 | 33 | @Override 34 | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { 35 | if (evt instanceof IdleStateEvent) { 36 | IdleStateEvent event = (IdleStateEvent) evt; 37 | String type = ""; 38 | if (event.state() == IdleState.READER_IDLE) { 39 | type = "read idle"; 40 | } else if (event.state() == IdleState.WRITER_IDLE) { 41 | type = "write idle"; 42 | } else if (event.state() == IdleState.ALL_IDLE) { 43 | type = "all idle"; 44 | } 45 | log.debug(ctx.channel().remoteAddress() + "超时类型:" + type); 46 | sendPingMsg(ctx); 47 | } else { 48 | super.userEventTriggered(ctx, evt); 49 | } 50 | } 51 | 52 | /** 53 | * 发送ping消息 54 | * @param context 55 | */ 56 | protected void sendPingMsg(ChannelHandlerContext context) { 57 | context.writeAndFlush( 58 | MessageBase.newBuilder() 59 | .setClientId(CLIENTID) 60 | .setCmd(CommandType.PING) 61 | .setData("This is a ping msg") 62 | .build() 63 | ); 64 | heartbeatCount++; 65 | log.info("Client sent ping msg to " + context.channel().remoteAddress() + ", count: " + heartbeatCount); 66 | } 67 | 68 | /** 69 | * 处理断开重连 70 | */ 71 | @Override 72 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 73 | final EventLoop eventLoop = ctx.channel().eventLoop(); 74 | eventLoop.schedule(() -> nettyClient.doConnect(new Bootstrap(), eventLoop), 10L, TimeUnit.SECONDS); 75 | super.channelInactive(ctx); 76 | } 77 | 78 | @Override 79 | protected void channelRead0(ChannelHandlerContext ctx, Message msg) throws Exception { 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/netty/client/handler/LogicClientHandler.java: -------------------------------------------------------------------------------- 1 | package com.netty.client.handler; 2 | 3 | 4 | import org.apache.log4j.Logger; 5 | 6 | import com.netty.common.protobuf.Command.CommandType; 7 | import com.netty.common.protobuf.Message.MessageBase; 8 | 9 | import io.netty.channel.ChannelHandlerContext; 10 | import io.netty.channel.SimpleChannelInboundHandler; 11 | 12 | public class LogicClientHandler extends SimpleChannelInboundHandler{ 13 | public Logger log = Logger.getLogger(this.getClass()); 14 | 15 | private final static String CLIENTID = "123456789"; 16 | 17 | // 连接成功后,向server发送消息 18 | @Override 19 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 20 | MessageBase.Builder authMsg = MessageBase.newBuilder(); 21 | authMsg.setClientId(CLIENTID); 22 | authMsg.setCmd(CommandType.AUTH); 23 | authMsg.setData("This is auth data"); 24 | 25 | ctx.writeAndFlush(authMsg.build()); 26 | } 27 | 28 | @Override 29 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 30 | log.debug("连接断开 "); 31 | } 32 | 33 | @Override 34 | protected void channelRead0(ChannelHandlerContext ctx, MessageBase msg) throws Exception { 35 | if(msg.getCmd().equals(CommandType.AUTH_BACK)){ 36 | log.debug("验证成功"); 37 | ctx.writeAndFlush( 38 | MessageBase.newBuilder() 39 | .setClientId(CLIENTID) 40 | .setCmd(CommandType.PUSH_DATA) 41 | .setData("This is upload data") 42 | .build() 43 | ); 44 | 45 | }else if(msg.getCmd().equals(CommandType.PING)){ 46 | //接收到server发送的ping指令 47 | log.info(msg.getData()); 48 | 49 | }else if(msg.getCmd().equals(CommandType.PONG)){ 50 | //接收到server发送的pong指令 51 | log.info(msg.getData()); 52 | 53 | }else if(msg.getCmd().equals(CommandType.PUSH_DATA)){ 54 | //接收到server推送数据 55 | log.info(msg.getData()); 56 | 57 | }else if(msg.getCmd().equals(CommandType.PUSH_DATA_BACK)){ 58 | //接收到server返回数据 59 | log.info(msg.getData()); 60 | 61 | }else{ 62 | log.info(msg.getData()); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/netty/common/protobuf/Command.java: -------------------------------------------------------------------------------- 1 | // Generated by the protocol buffer compiler. DO NOT EDIT! 2 | // source: Command.proto 3 | 4 | package com.netty.common.protobuf; 5 | 6 | public final class Command { 7 | private Command() {} 8 | public static void registerAllExtensions( 9 | com.google.protobuf.ExtensionRegistryLite registry) { 10 | } 11 | 12 | public static void registerAllExtensions( 13 | com.google.protobuf.ExtensionRegistry registry) { 14 | registerAllExtensions( 15 | (com.google.protobuf.ExtensionRegistryLite) registry); 16 | } 17 | /** 18 | *
 19 |    **
 20 |    * 指令类型
 21 |    * 
22 | * 23 | * Protobuf enum {@code CommandType} 24 | */ 25 | public enum CommandType 26 | implements com.google.protobuf.ProtocolMessageEnum { 27 | /** 28 | *
 29 |      **
 30 |      * 验证
 31 |      * 
32 | * 33 | * AUTH = 1; 34 | */ 35 | AUTH(1), 36 | /** 37 | *
 38 |      **
 39 |      * ping
 40 |      * 
41 | * 42 | * PING = 2; 43 | */ 44 | PING(2), 45 | /** 46 | *
 47 |      **
 48 |      * pong
 49 |      * 
50 | * 51 | * PONG = 3; 52 | */ 53 | PONG(3), 54 | /** 55 | *
 56 |      **
 57 |      * 上传数据
 58 |      * 
59 | * 60 | * UPLOAD_DATA = 4; 61 | */ 62 | UPLOAD_DATA(4), 63 | /** 64 | *
 65 |      **
 66 |      * 推送数据
 67 |      * 
68 | * 69 | * PUSH_DATA = 5; 70 | */ 71 | PUSH_DATA(5), 72 | /** 73 | *
 74 |      **
 75 |      * 验证返回
 76 |      * 
77 | * 78 | * AUTH_BACK = 11; 79 | */ 80 | AUTH_BACK(11), 81 | /** 82 | * UPLOAD_DATA_BACK = 14; 83 | */ 84 | UPLOAD_DATA_BACK(14), 85 | /** 86 | * PUSH_DATA_BACK = 15; 87 | */ 88 | PUSH_DATA_BACK(15), 89 | ; 90 | 91 | /** 92 | *
 93 |      **
 94 |      * 验证
 95 |      * 
96 | * 97 | * AUTH = 1; 98 | */ 99 | public static final int AUTH_VALUE = 1; 100 | /** 101 | *
102 |      **
103 |      * ping
104 |      * 
105 | * 106 | * PING = 2; 107 | */ 108 | public static final int PING_VALUE = 2; 109 | /** 110 | *
111 |      **
112 |      * pong
113 |      * 
114 | * 115 | * PONG = 3; 116 | */ 117 | public static final int PONG_VALUE = 3; 118 | /** 119 | *
120 |      **
121 |      * 上传数据
122 |      * 
123 | * 124 | * UPLOAD_DATA = 4; 125 | */ 126 | public static final int UPLOAD_DATA_VALUE = 4; 127 | /** 128 | *
129 |      **
130 |      * 推送数据
131 |      * 
132 | * 133 | * PUSH_DATA = 5; 134 | */ 135 | public static final int PUSH_DATA_VALUE = 5; 136 | /** 137 | *
138 |      **
139 |      * 验证返回
140 |      * 
141 | * 142 | * AUTH_BACK = 11; 143 | */ 144 | public static final int AUTH_BACK_VALUE = 11; 145 | /** 146 | * UPLOAD_DATA_BACK = 14; 147 | */ 148 | public static final int UPLOAD_DATA_BACK_VALUE = 14; 149 | /** 150 | * PUSH_DATA_BACK = 15; 151 | */ 152 | public static final int PUSH_DATA_BACK_VALUE = 15; 153 | 154 | 155 | public final int getNumber() { 156 | return value; 157 | } 158 | 159 | /** 160 | * @deprecated Use {@link #forNumber(int)} instead. 161 | */ 162 | @java.lang.Deprecated 163 | public static CommandType valueOf(int value) { 164 | return forNumber(value); 165 | } 166 | 167 | public static CommandType forNumber(int value) { 168 | switch (value) { 169 | case 1: return AUTH; 170 | case 2: return PING; 171 | case 3: return PONG; 172 | case 4: return UPLOAD_DATA; 173 | case 5: return PUSH_DATA; 174 | case 11: return AUTH_BACK; 175 | case 14: return UPLOAD_DATA_BACK; 176 | case 15: return PUSH_DATA_BACK; 177 | default: return null; 178 | } 179 | } 180 | 181 | public static com.google.protobuf.Internal.EnumLiteMap 182 | internalGetValueMap() { 183 | return internalValueMap; 184 | } 185 | private static final com.google.protobuf.Internal.EnumLiteMap< 186 | CommandType> internalValueMap = 187 | new com.google.protobuf.Internal.EnumLiteMap() { 188 | public CommandType findValueByNumber(int number) { 189 | return CommandType.forNumber(number); 190 | } 191 | }; 192 | 193 | public final com.google.protobuf.Descriptors.EnumValueDescriptor 194 | getValueDescriptor() { 195 | return getDescriptor().getValues().get(ordinal()); 196 | } 197 | public final com.google.protobuf.Descriptors.EnumDescriptor 198 | getDescriptorForType() { 199 | return getDescriptor(); 200 | } 201 | public static final com.google.protobuf.Descriptors.EnumDescriptor 202 | getDescriptor() { 203 | return com.netty.common.protobuf.Command.getDescriptor().getEnumTypes().get(0); 204 | } 205 | 206 | private static final CommandType[] VALUES = values(); 207 | 208 | public static CommandType valueOf( 209 | com.google.protobuf.Descriptors.EnumValueDescriptor desc) { 210 | if (desc.getType() != getDescriptor()) { 211 | throw new java.lang.IllegalArgumentException( 212 | "EnumValueDescriptor is not for this type."); 213 | } 214 | return VALUES[desc.getIndex()]; 215 | } 216 | 217 | private final int value; 218 | 219 | private CommandType(int value) { 220 | this.value = value; 221 | } 222 | 223 | // @@protoc_insertion_point(enum_scope:CommandType) 224 | } 225 | 226 | 227 | public static com.google.protobuf.Descriptors.FileDescriptor 228 | getDescriptor() { 229 | return descriptor; 230 | } 231 | private static com.google.protobuf.Descriptors.FileDescriptor 232 | descriptor; 233 | static { 234 | java.lang.String[] descriptorData = { 235 | "\n\rCommand.proto\032\rCommand.proto*\204\001\n\013Comma" + 236 | "ndType\022\010\n\004AUTH\020\001\022\010\n\004PING\020\002\022\010\n\004PONG\020\003\022\017\n\013" + 237 | "UPLOAD_DATA\020\004\022\r\n\tPUSH_DATA\020\005\022\r\n\tAUTH_BAC" + 238 | "K\020\013\022\024\n\020UPLOAD_DATA_BACK\020\016\022\022\n\016PUSH_DATA_B" + 239 | "ACK\020\017B$\n\031com.netty.common.protobufB\007Comm" + 240 | "and" 241 | }; 242 | com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = 243 | new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { 244 | public com.google.protobuf.ExtensionRegistry assignDescriptors( 245 | com.google.protobuf.Descriptors.FileDescriptor root) { 246 | descriptor = root; 247 | return null; 248 | } 249 | }; 250 | com.google.protobuf.Descriptors.FileDescriptor 251 | .internalBuildGeneratedFileFrom(descriptorData, 252 | new com.google.protobuf.Descriptors.FileDescriptor[] { 253 | com.netty.common.protobuf.Command.getDescriptor(), 254 | }, assigner); 255 | com.netty.common.protobuf.Command.getDescriptor(); 256 | } 257 | 258 | // @@protoc_insertion_point(outer_class_scope) 259 | } 260 | -------------------------------------------------------------------------------- /src/main/java/com/netty/common/protobuf/Command.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | option java_package="com.netty.common.protobuf"; 4 | option java_outer_classname = "Command"; 5 | import "Command.proto"; 6 | /** 7 | * 指令类型 8 | */ 9 | enum CommandType { 10 | /** 11 | * 验证 12 | */ 13 | AUTH = 1; 14 | /** 15 | * ping 16 | */ 17 | PING = 2; 18 | /** 19 | * pong 20 | */ 21 | PONG = 3; 22 | /** 23 | * 上传数据 24 | */ 25 | UPLOAD_DATA = 4; 26 | /** 27 | * 推送数据 28 | */ 29 | PUSH_DATA = 5; 30 | 31 | /** 32 | * 验证返回 33 | */ 34 | AUTH_BACK = 11; 35 | 36 | UPLOAD_DATA_BACK = 14; 37 | 38 | PUSH_DATA_BACK = 15; 39 | } -------------------------------------------------------------------------------- /src/main/java/com/netty/common/protobuf/Message.java: -------------------------------------------------------------------------------- 1 | // Generated by the protocol buffer compiler. DO NOT EDIT! 2 | // source: Message.proto 3 | 4 | package com.netty.common.protobuf; 5 | 6 | public final class Message { 7 | private Message() {} 8 | public static void registerAllExtensions( 9 | com.google.protobuf.ExtensionRegistryLite registry) { 10 | } 11 | 12 | public static void registerAllExtensions( 13 | com.google.protobuf.ExtensionRegistry registry) { 14 | registerAllExtensions( 15 | (com.google.protobuf.ExtensionRegistryLite) registry); 16 | } 17 | public interface MessageBaseOrBuilder extends 18 | // @@protoc_insertion_point(interface_extends:MessageBase) 19 | com.google.protobuf.MessageOrBuilder { 20 | 21 | /** 22 | * required string clientId = 1; 23 | */ 24 | boolean hasClientId(); 25 | /** 26 | * required string clientId = 1; 27 | */ 28 | java.lang.String getClientId(); 29 | /** 30 | * required string clientId = 1; 31 | */ 32 | com.google.protobuf.ByteString 33 | getClientIdBytes(); 34 | 35 | /** 36 | * required .CommandType cmd = 2; 37 | */ 38 | boolean hasCmd(); 39 | /** 40 | * required .CommandType cmd = 2; 41 | */ 42 | com.netty.common.protobuf.Command.CommandType getCmd(); 43 | 44 | /** 45 | * optional string data = 3; 46 | */ 47 | boolean hasData(); 48 | /** 49 | * optional string data = 3; 50 | */ 51 | java.lang.String getData(); 52 | /** 53 | * optional string data = 3; 54 | */ 55 | com.google.protobuf.ByteString 56 | getDataBytes(); 57 | } 58 | /** 59 | * Protobuf type {@code MessageBase} 60 | */ 61 | public static final class MessageBase extends 62 | com.google.protobuf.GeneratedMessageV3 implements 63 | // @@protoc_insertion_point(message_implements:MessageBase) 64 | MessageBaseOrBuilder { 65 | // Use MessageBase.newBuilder() to construct. 66 | private MessageBase(com.google.protobuf.GeneratedMessageV3.Builder builder) { 67 | super(builder); 68 | } 69 | private MessageBase() { 70 | clientId_ = ""; 71 | cmd_ = 1; 72 | data_ = ""; 73 | } 74 | 75 | @java.lang.Override 76 | public final com.google.protobuf.UnknownFieldSet 77 | getUnknownFields() { 78 | return this.unknownFields; 79 | } 80 | private MessageBase( 81 | com.google.protobuf.CodedInputStream input, 82 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 83 | throws com.google.protobuf.InvalidProtocolBufferException { 84 | this(); 85 | int mutable_bitField0_ = 0; 86 | com.google.protobuf.UnknownFieldSet.Builder unknownFields = 87 | com.google.protobuf.UnknownFieldSet.newBuilder(); 88 | try { 89 | boolean done = false; 90 | while (!done) { 91 | int tag = input.readTag(); 92 | switch (tag) { 93 | case 0: 94 | done = true; 95 | break; 96 | default: { 97 | if (!parseUnknownField(input, unknownFields, 98 | extensionRegistry, tag)) { 99 | done = true; 100 | } 101 | break; 102 | } 103 | case 10: { 104 | com.google.protobuf.ByteString bs = input.readBytes(); 105 | bitField0_ |= 0x00000001; 106 | clientId_ = bs; 107 | break; 108 | } 109 | case 16: { 110 | int rawValue = input.readEnum(); 111 | com.netty.common.protobuf.Command.CommandType value = com.netty.common.protobuf.Command.CommandType.valueOf(rawValue); 112 | if (value == null) { 113 | unknownFields.mergeVarintField(2, rawValue); 114 | } else { 115 | bitField0_ |= 0x00000002; 116 | cmd_ = rawValue; 117 | } 118 | break; 119 | } 120 | case 26: { 121 | com.google.protobuf.ByteString bs = input.readBytes(); 122 | bitField0_ |= 0x00000004; 123 | data_ = bs; 124 | break; 125 | } 126 | } 127 | } 128 | } catch (com.google.protobuf.InvalidProtocolBufferException e) { 129 | throw e.setUnfinishedMessage(this); 130 | } catch (java.io.IOException e) { 131 | throw new com.google.protobuf.InvalidProtocolBufferException( 132 | e).setUnfinishedMessage(this); 133 | } finally { 134 | this.unknownFields = unknownFields.build(); 135 | makeExtensionsImmutable(); 136 | } 137 | } 138 | public static final com.google.protobuf.Descriptors.Descriptor 139 | getDescriptor() { 140 | return com.netty.common.protobuf.Message.internal_static_MessageBase_descriptor; 141 | } 142 | 143 | protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable 144 | internalGetFieldAccessorTable() { 145 | return com.netty.common.protobuf.Message.internal_static_MessageBase_fieldAccessorTable 146 | .ensureFieldAccessorsInitialized( 147 | com.netty.common.protobuf.Message.MessageBase.class, com.netty.common.protobuf.Message.MessageBase.Builder.class); 148 | } 149 | 150 | private int bitField0_; 151 | public static final int CLIENTID_FIELD_NUMBER = 1; 152 | private volatile java.lang.Object clientId_; 153 | /** 154 | * required string clientId = 1; 155 | */ 156 | public boolean hasClientId() { 157 | return ((bitField0_ & 0x00000001) == 0x00000001); 158 | } 159 | /** 160 | * required string clientId = 1; 161 | */ 162 | public java.lang.String getClientId() { 163 | java.lang.Object ref = clientId_; 164 | if (ref instanceof java.lang.String) { 165 | return (java.lang.String) ref; 166 | } else { 167 | com.google.protobuf.ByteString bs = 168 | (com.google.protobuf.ByteString) ref; 169 | java.lang.String s = bs.toStringUtf8(); 170 | if (bs.isValidUtf8()) { 171 | clientId_ = s; 172 | } 173 | return s; 174 | } 175 | } 176 | /** 177 | * required string clientId = 1; 178 | */ 179 | public com.google.protobuf.ByteString 180 | getClientIdBytes() { 181 | java.lang.Object ref = clientId_; 182 | if (ref instanceof java.lang.String) { 183 | com.google.protobuf.ByteString b = 184 | com.google.protobuf.ByteString.copyFromUtf8( 185 | (java.lang.String) ref); 186 | clientId_ = b; 187 | return b; 188 | } else { 189 | return (com.google.protobuf.ByteString) ref; 190 | } 191 | } 192 | 193 | public static final int CMD_FIELD_NUMBER = 2; 194 | private int cmd_; 195 | /** 196 | * required .CommandType cmd = 2; 197 | */ 198 | public boolean hasCmd() { 199 | return ((bitField0_ & 0x00000002) == 0x00000002); 200 | } 201 | /** 202 | * required .CommandType cmd = 2; 203 | */ 204 | public com.netty.common.protobuf.Command.CommandType getCmd() { 205 | com.netty.common.protobuf.Command.CommandType result = com.netty.common.protobuf.Command.CommandType.valueOf(cmd_); 206 | return result == null ? com.netty.common.protobuf.Command.CommandType.AUTH : result; 207 | } 208 | 209 | public static final int DATA_FIELD_NUMBER = 3; 210 | private volatile java.lang.Object data_; 211 | /** 212 | * optional string data = 3; 213 | */ 214 | public boolean hasData() { 215 | return ((bitField0_ & 0x00000004) == 0x00000004); 216 | } 217 | /** 218 | * optional string data = 3; 219 | */ 220 | public java.lang.String getData() { 221 | java.lang.Object ref = data_; 222 | if (ref instanceof java.lang.String) { 223 | return (java.lang.String) ref; 224 | } else { 225 | com.google.protobuf.ByteString bs = 226 | (com.google.protobuf.ByteString) ref; 227 | java.lang.String s = bs.toStringUtf8(); 228 | if (bs.isValidUtf8()) { 229 | data_ = s; 230 | } 231 | return s; 232 | } 233 | } 234 | /** 235 | * optional string data = 3; 236 | */ 237 | public com.google.protobuf.ByteString 238 | getDataBytes() { 239 | java.lang.Object ref = data_; 240 | if (ref instanceof java.lang.String) { 241 | com.google.protobuf.ByteString b = 242 | com.google.protobuf.ByteString.copyFromUtf8( 243 | (java.lang.String) ref); 244 | data_ = b; 245 | return b; 246 | } else { 247 | return (com.google.protobuf.ByteString) ref; 248 | } 249 | } 250 | 251 | private byte memoizedIsInitialized = -1; 252 | public final boolean isInitialized() { 253 | byte isInitialized = memoizedIsInitialized; 254 | if (isInitialized == 1) return true; 255 | if (isInitialized == 0) return false; 256 | 257 | if (!hasClientId()) { 258 | memoizedIsInitialized = 0; 259 | return false; 260 | } 261 | if (!hasCmd()) { 262 | memoizedIsInitialized = 0; 263 | return false; 264 | } 265 | memoizedIsInitialized = 1; 266 | return true; 267 | } 268 | 269 | public void writeTo(com.google.protobuf.CodedOutputStream output) 270 | throws java.io.IOException { 271 | if (((bitField0_ & 0x00000001) == 0x00000001)) { 272 | com.google.protobuf.GeneratedMessageV3.writeString(output, 1, clientId_); 273 | } 274 | if (((bitField0_ & 0x00000002) == 0x00000002)) { 275 | output.writeEnum(2, cmd_); 276 | } 277 | if (((bitField0_ & 0x00000004) == 0x00000004)) { 278 | com.google.protobuf.GeneratedMessageV3.writeString(output, 3, data_); 279 | } 280 | unknownFields.writeTo(output); 281 | } 282 | 283 | public int getSerializedSize() { 284 | int size = memoizedSize; 285 | if (size != -1) return size; 286 | 287 | size = 0; 288 | if (((bitField0_ & 0x00000001) == 0x00000001)) { 289 | size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, clientId_); 290 | } 291 | if (((bitField0_ & 0x00000002) == 0x00000002)) { 292 | size += com.google.protobuf.CodedOutputStream 293 | .computeEnumSize(2, cmd_); 294 | } 295 | if (((bitField0_ & 0x00000004) == 0x00000004)) { 296 | size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, data_); 297 | } 298 | size += unknownFields.getSerializedSize(); 299 | memoizedSize = size; 300 | return size; 301 | } 302 | 303 | private static final long serialVersionUID = 0L; 304 | @java.lang.Override 305 | public boolean equals(final java.lang.Object obj) { 306 | if (obj == this) { 307 | return true; 308 | } 309 | if (!(obj instanceof com.netty.common.protobuf.Message.MessageBase)) { 310 | return super.equals(obj); 311 | } 312 | com.netty.common.protobuf.Message.MessageBase other = (com.netty.common.protobuf.Message.MessageBase) obj; 313 | 314 | boolean result = true; 315 | result = result && (hasClientId() == other.hasClientId()); 316 | if (hasClientId()) { 317 | result = result && getClientId() 318 | .equals(other.getClientId()); 319 | } 320 | result = result && (hasCmd() == other.hasCmd()); 321 | if (hasCmd()) { 322 | result = result && cmd_ == other.cmd_; 323 | } 324 | result = result && (hasData() == other.hasData()); 325 | if (hasData()) { 326 | result = result && getData() 327 | .equals(other.getData()); 328 | } 329 | result = result && unknownFields.equals(other.unknownFields); 330 | return result; 331 | } 332 | 333 | @java.lang.Override 334 | public int hashCode() { 335 | if (memoizedHashCode != 0) { 336 | return memoizedHashCode; 337 | } 338 | int hash = 41; 339 | hash = (19 * hash) + getDescriptorForType().hashCode(); 340 | if (hasClientId()) { 341 | hash = (37 * hash) + CLIENTID_FIELD_NUMBER; 342 | hash = (53 * hash) + getClientId().hashCode(); 343 | } 344 | if (hasCmd()) { 345 | hash = (37 * hash) + CMD_FIELD_NUMBER; 346 | hash = (53 * hash) + cmd_; 347 | } 348 | if (hasData()) { 349 | hash = (37 * hash) + DATA_FIELD_NUMBER; 350 | hash = (53 * hash) + getData().hashCode(); 351 | } 352 | hash = (29 * hash) + unknownFields.hashCode(); 353 | memoizedHashCode = hash; 354 | return hash; 355 | } 356 | 357 | public static com.netty.common.protobuf.Message.MessageBase parseFrom( 358 | com.google.protobuf.ByteString data) 359 | throws com.google.protobuf.InvalidProtocolBufferException { 360 | return PARSER.parseFrom(data); 361 | } 362 | public static com.netty.common.protobuf.Message.MessageBase parseFrom( 363 | com.google.protobuf.ByteString data, 364 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 365 | throws com.google.protobuf.InvalidProtocolBufferException { 366 | return PARSER.parseFrom(data, extensionRegistry); 367 | } 368 | public static com.netty.common.protobuf.Message.MessageBase parseFrom(byte[] data) 369 | throws com.google.protobuf.InvalidProtocolBufferException { 370 | return PARSER.parseFrom(data); 371 | } 372 | public static com.netty.common.protobuf.Message.MessageBase parseFrom( 373 | byte[] data, 374 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 375 | throws com.google.protobuf.InvalidProtocolBufferException { 376 | return PARSER.parseFrom(data, extensionRegistry); 377 | } 378 | public static com.netty.common.protobuf.Message.MessageBase parseFrom(java.io.InputStream input) 379 | throws java.io.IOException { 380 | return com.google.protobuf.GeneratedMessageV3 381 | .parseWithIOException(PARSER, input); 382 | } 383 | public static com.netty.common.protobuf.Message.MessageBase parseFrom( 384 | java.io.InputStream input, 385 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 386 | throws java.io.IOException { 387 | return com.google.protobuf.GeneratedMessageV3 388 | .parseWithIOException(PARSER, input, extensionRegistry); 389 | } 390 | public static com.netty.common.protobuf.Message.MessageBase parseDelimitedFrom(java.io.InputStream input) 391 | throws java.io.IOException { 392 | return com.google.protobuf.GeneratedMessageV3 393 | .parseDelimitedWithIOException(PARSER, input); 394 | } 395 | public static com.netty.common.protobuf.Message.MessageBase parseDelimitedFrom( 396 | java.io.InputStream input, 397 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 398 | throws java.io.IOException { 399 | return com.google.protobuf.GeneratedMessageV3 400 | .parseDelimitedWithIOException(PARSER, input, extensionRegistry); 401 | } 402 | public static com.netty.common.protobuf.Message.MessageBase parseFrom( 403 | com.google.protobuf.CodedInputStream input) 404 | throws java.io.IOException { 405 | return com.google.protobuf.GeneratedMessageV3 406 | .parseWithIOException(PARSER, input); 407 | } 408 | public static com.netty.common.protobuf.Message.MessageBase parseFrom( 409 | com.google.protobuf.CodedInputStream input, 410 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 411 | throws java.io.IOException { 412 | return com.google.protobuf.GeneratedMessageV3 413 | .parseWithIOException(PARSER, input, extensionRegistry); 414 | } 415 | 416 | public Builder newBuilderForType() { return newBuilder(); } 417 | public static Builder newBuilder() { 418 | return DEFAULT_INSTANCE.toBuilder(); 419 | } 420 | public static Builder newBuilder(com.netty.common.protobuf.Message.MessageBase prototype) { 421 | return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); 422 | } 423 | public Builder toBuilder() { 424 | return this == DEFAULT_INSTANCE 425 | ? new Builder() : new Builder().mergeFrom(this); 426 | } 427 | 428 | @java.lang.Override 429 | protected Builder newBuilderForType( 430 | com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { 431 | Builder builder = new Builder(parent); 432 | return builder; 433 | } 434 | /** 435 | * Protobuf type {@code MessageBase} 436 | */ 437 | public static final class Builder extends 438 | com.google.protobuf.GeneratedMessageV3.Builder implements 439 | // @@protoc_insertion_point(builder_implements:MessageBase) 440 | com.netty.common.protobuf.Message.MessageBaseOrBuilder { 441 | public static final com.google.protobuf.Descriptors.Descriptor 442 | getDescriptor() { 443 | return com.netty.common.protobuf.Message.internal_static_MessageBase_descriptor; 444 | } 445 | 446 | protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable 447 | internalGetFieldAccessorTable() { 448 | return com.netty.common.protobuf.Message.internal_static_MessageBase_fieldAccessorTable 449 | .ensureFieldAccessorsInitialized( 450 | com.netty.common.protobuf.Message.MessageBase.class, com.netty.common.protobuf.Message.MessageBase.Builder.class); 451 | } 452 | 453 | // Construct using com.netty.common.protobuf.Message.MessageBase.newBuilder() 454 | private Builder() { 455 | maybeForceBuilderInitialization(); 456 | } 457 | 458 | private Builder( 459 | com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { 460 | super(parent); 461 | maybeForceBuilderInitialization(); 462 | } 463 | private void maybeForceBuilderInitialization() { 464 | if (com.google.protobuf.GeneratedMessageV3 465 | .alwaysUseFieldBuilders) { 466 | } 467 | } 468 | public Builder clear() { 469 | super.clear(); 470 | clientId_ = ""; 471 | bitField0_ = (bitField0_ & ~0x00000001); 472 | cmd_ = 1; 473 | bitField0_ = (bitField0_ & ~0x00000002); 474 | data_ = ""; 475 | bitField0_ = (bitField0_ & ~0x00000004); 476 | return this; 477 | } 478 | 479 | public com.google.protobuf.Descriptors.Descriptor 480 | getDescriptorForType() { 481 | return com.netty.common.protobuf.Message.internal_static_MessageBase_descriptor; 482 | } 483 | 484 | public com.netty.common.protobuf.Message.MessageBase getDefaultInstanceForType() { 485 | return com.netty.common.protobuf.Message.MessageBase.getDefaultInstance(); 486 | } 487 | 488 | public com.netty.common.protobuf.Message.MessageBase build() { 489 | com.netty.common.protobuf.Message.MessageBase result = buildPartial(); 490 | if (!result.isInitialized()) { 491 | throw newUninitializedMessageException(result); 492 | } 493 | return result; 494 | } 495 | 496 | public com.netty.common.protobuf.Message.MessageBase buildPartial() { 497 | com.netty.common.protobuf.Message.MessageBase result = new com.netty.common.protobuf.Message.MessageBase(this); 498 | int from_bitField0_ = bitField0_; 499 | int to_bitField0_ = 0; 500 | if (((from_bitField0_ & 0x00000001) == 0x00000001)) { 501 | to_bitField0_ |= 0x00000001; 502 | } 503 | result.clientId_ = clientId_; 504 | if (((from_bitField0_ & 0x00000002) == 0x00000002)) { 505 | to_bitField0_ |= 0x00000002; 506 | } 507 | result.cmd_ = cmd_; 508 | if (((from_bitField0_ & 0x00000004) == 0x00000004)) { 509 | to_bitField0_ |= 0x00000004; 510 | } 511 | result.data_ = data_; 512 | result.bitField0_ = to_bitField0_; 513 | onBuilt(); 514 | return result; 515 | } 516 | 517 | public Builder clone() { 518 | return (Builder) super.clone(); 519 | } 520 | public Builder setField( 521 | com.google.protobuf.Descriptors.FieldDescriptor field, 522 | Object value) { 523 | return (Builder) super.setField(field, value); 524 | } 525 | public Builder clearField( 526 | com.google.protobuf.Descriptors.FieldDescriptor field) { 527 | return (Builder) super.clearField(field); 528 | } 529 | public Builder clearOneof( 530 | com.google.protobuf.Descriptors.OneofDescriptor oneof) { 531 | return (Builder) super.clearOneof(oneof); 532 | } 533 | public Builder setRepeatedField( 534 | com.google.protobuf.Descriptors.FieldDescriptor field, 535 | int index, Object value) { 536 | return (Builder) super.setRepeatedField(field, index, value); 537 | } 538 | public Builder addRepeatedField( 539 | com.google.protobuf.Descriptors.FieldDescriptor field, 540 | Object value) { 541 | return (Builder) super.addRepeatedField(field, value); 542 | } 543 | public Builder mergeFrom(com.google.protobuf.Message other) { 544 | if (other instanceof com.netty.common.protobuf.Message.MessageBase) { 545 | return mergeFrom((com.netty.common.protobuf.Message.MessageBase)other); 546 | } else { 547 | super.mergeFrom(other); 548 | return this; 549 | } 550 | } 551 | 552 | public Builder mergeFrom(com.netty.common.protobuf.Message.MessageBase other) { 553 | if (other == com.netty.common.protobuf.Message.MessageBase.getDefaultInstance()) return this; 554 | if (other.hasClientId()) { 555 | bitField0_ |= 0x00000001; 556 | clientId_ = other.clientId_; 557 | onChanged(); 558 | } 559 | if (other.hasCmd()) { 560 | setCmd(other.getCmd()); 561 | } 562 | if (other.hasData()) { 563 | bitField0_ |= 0x00000004; 564 | data_ = other.data_; 565 | onChanged(); 566 | } 567 | this.mergeUnknownFields(other.unknownFields); 568 | onChanged(); 569 | return this; 570 | } 571 | 572 | public final boolean isInitialized() { 573 | if (!hasClientId()) { 574 | return false; 575 | } 576 | if (!hasCmd()) { 577 | return false; 578 | } 579 | return true; 580 | } 581 | 582 | public Builder mergeFrom( 583 | com.google.protobuf.CodedInputStream input, 584 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 585 | throws java.io.IOException { 586 | com.netty.common.protobuf.Message.MessageBase parsedMessage = null; 587 | try { 588 | parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); 589 | } catch (com.google.protobuf.InvalidProtocolBufferException e) { 590 | parsedMessage = (com.netty.common.protobuf.Message.MessageBase) e.getUnfinishedMessage(); 591 | throw e.unwrapIOException(); 592 | } finally { 593 | if (parsedMessage != null) { 594 | mergeFrom(parsedMessage); 595 | } 596 | } 597 | return this; 598 | } 599 | private int bitField0_; 600 | 601 | private java.lang.Object clientId_ = ""; 602 | /** 603 | * required string clientId = 1; 604 | */ 605 | public boolean hasClientId() { 606 | return ((bitField0_ & 0x00000001) == 0x00000001); 607 | } 608 | /** 609 | * required string clientId = 1; 610 | */ 611 | public java.lang.String getClientId() { 612 | java.lang.Object ref = clientId_; 613 | if (!(ref instanceof java.lang.String)) { 614 | com.google.protobuf.ByteString bs = 615 | (com.google.protobuf.ByteString) ref; 616 | java.lang.String s = bs.toStringUtf8(); 617 | if (bs.isValidUtf8()) { 618 | clientId_ = s; 619 | } 620 | return s; 621 | } else { 622 | return (java.lang.String) ref; 623 | } 624 | } 625 | /** 626 | * required string clientId = 1; 627 | */ 628 | public com.google.protobuf.ByteString 629 | getClientIdBytes() { 630 | java.lang.Object ref = clientId_; 631 | if (ref instanceof String) { 632 | com.google.protobuf.ByteString b = 633 | com.google.protobuf.ByteString.copyFromUtf8( 634 | (java.lang.String) ref); 635 | clientId_ = b; 636 | return b; 637 | } else { 638 | return (com.google.protobuf.ByteString) ref; 639 | } 640 | } 641 | /** 642 | * required string clientId = 1; 643 | */ 644 | public Builder setClientId( 645 | java.lang.String value) { 646 | if (value == null) { 647 | throw new NullPointerException(); 648 | } 649 | bitField0_ |= 0x00000001; 650 | clientId_ = value; 651 | onChanged(); 652 | return this; 653 | } 654 | /** 655 | * required string clientId = 1; 656 | */ 657 | public Builder clearClientId() { 658 | bitField0_ = (bitField0_ & ~0x00000001); 659 | clientId_ = getDefaultInstance().getClientId(); 660 | onChanged(); 661 | return this; 662 | } 663 | /** 664 | * required string clientId = 1; 665 | */ 666 | public Builder setClientIdBytes( 667 | com.google.protobuf.ByteString value) { 668 | if (value == null) { 669 | throw new NullPointerException(); 670 | } 671 | bitField0_ |= 0x00000001; 672 | clientId_ = value; 673 | onChanged(); 674 | return this; 675 | } 676 | 677 | private int cmd_ = 1; 678 | /** 679 | * required .CommandType cmd = 2; 680 | */ 681 | public boolean hasCmd() { 682 | return ((bitField0_ & 0x00000002) == 0x00000002); 683 | } 684 | /** 685 | * required .CommandType cmd = 2; 686 | */ 687 | public com.netty.common.protobuf.Command.CommandType getCmd() { 688 | com.netty.common.protobuf.Command.CommandType result = com.netty.common.protobuf.Command.CommandType.valueOf(cmd_); 689 | return result == null ? com.netty.common.protobuf.Command.CommandType.AUTH : result; 690 | } 691 | /** 692 | * required .CommandType cmd = 2; 693 | */ 694 | public Builder setCmd(com.netty.common.protobuf.Command.CommandType value) { 695 | if (value == null) { 696 | throw new NullPointerException(); 697 | } 698 | bitField0_ |= 0x00000002; 699 | cmd_ = value.getNumber(); 700 | onChanged(); 701 | return this; 702 | } 703 | /** 704 | * required .CommandType cmd = 2; 705 | */ 706 | public Builder clearCmd() { 707 | bitField0_ = (bitField0_ & ~0x00000002); 708 | cmd_ = 1; 709 | onChanged(); 710 | return this; 711 | } 712 | 713 | private java.lang.Object data_ = ""; 714 | /** 715 | * optional string data = 3; 716 | */ 717 | public boolean hasData() { 718 | return ((bitField0_ & 0x00000004) == 0x00000004); 719 | } 720 | /** 721 | * optional string data = 3; 722 | */ 723 | public java.lang.String getData() { 724 | java.lang.Object ref = data_; 725 | if (!(ref instanceof java.lang.String)) { 726 | com.google.protobuf.ByteString bs = 727 | (com.google.protobuf.ByteString) ref; 728 | java.lang.String s = bs.toStringUtf8(); 729 | if (bs.isValidUtf8()) { 730 | data_ = s; 731 | } 732 | return s; 733 | } else { 734 | return (java.lang.String) ref; 735 | } 736 | } 737 | /** 738 | * optional string data = 3; 739 | */ 740 | public com.google.protobuf.ByteString 741 | getDataBytes() { 742 | java.lang.Object ref = data_; 743 | if (ref instanceof String) { 744 | com.google.protobuf.ByteString b = 745 | com.google.protobuf.ByteString.copyFromUtf8( 746 | (java.lang.String) ref); 747 | data_ = b; 748 | return b; 749 | } else { 750 | return (com.google.protobuf.ByteString) ref; 751 | } 752 | } 753 | /** 754 | * optional string data = 3; 755 | */ 756 | public Builder setData( 757 | java.lang.String value) { 758 | if (value == null) { 759 | throw new NullPointerException(); 760 | } 761 | bitField0_ |= 0x00000004; 762 | data_ = value; 763 | onChanged(); 764 | return this; 765 | } 766 | /** 767 | * optional string data = 3; 768 | */ 769 | public Builder clearData() { 770 | bitField0_ = (bitField0_ & ~0x00000004); 771 | data_ = getDefaultInstance().getData(); 772 | onChanged(); 773 | return this; 774 | } 775 | /** 776 | * optional string data = 3; 777 | */ 778 | public Builder setDataBytes( 779 | com.google.protobuf.ByteString value) { 780 | if (value == null) { 781 | throw new NullPointerException(); 782 | } 783 | bitField0_ |= 0x00000004; 784 | data_ = value; 785 | onChanged(); 786 | return this; 787 | } 788 | public final Builder setUnknownFields( 789 | final com.google.protobuf.UnknownFieldSet unknownFields) { 790 | return super.setUnknownFields(unknownFields); 791 | } 792 | 793 | public final Builder mergeUnknownFields( 794 | final com.google.protobuf.UnknownFieldSet unknownFields) { 795 | return super.mergeUnknownFields(unknownFields); 796 | } 797 | 798 | 799 | // @@protoc_insertion_point(builder_scope:MessageBase) 800 | } 801 | 802 | // @@protoc_insertion_point(class_scope:MessageBase) 803 | private static final com.netty.common.protobuf.Message.MessageBase DEFAULT_INSTANCE; 804 | static { 805 | DEFAULT_INSTANCE = new com.netty.common.protobuf.Message.MessageBase(); 806 | } 807 | 808 | public static com.netty.common.protobuf.Message.MessageBase getDefaultInstance() { 809 | return DEFAULT_INSTANCE; 810 | } 811 | 812 | @java.lang.Deprecated public static final com.google.protobuf.Parser 813 | PARSER = new com.google.protobuf.AbstractParser() { 814 | public MessageBase parsePartialFrom( 815 | com.google.protobuf.CodedInputStream input, 816 | com.google.protobuf.ExtensionRegistryLite extensionRegistry) 817 | throws com.google.protobuf.InvalidProtocolBufferException { 818 | return new MessageBase(input, extensionRegistry); 819 | } 820 | }; 821 | 822 | public static com.google.protobuf.Parser parser() { 823 | return PARSER; 824 | } 825 | 826 | @java.lang.Override 827 | public com.google.protobuf.Parser getParserForType() { 828 | return PARSER; 829 | } 830 | 831 | public com.netty.common.protobuf.Message.MessageBase getDefaultInstanceForType() { 832 | return DEFAULT_INSTANCE; 833 | } 834 | 835 | } 836 | 837 | private static final com.google.protobuf.Descriptors.Descriptor 838 | internal_static_MessageBase_descriptor; 839 | private static final 840 | com.google.protobuf.GeneratedMessageV3.FieldAccessorTable 841 | internal_static_MessageBase_fieldAccessorTable; 842 | 843 | public static com.google.protobuf.Descriptors.FileDescriptor 844 | getDescriptor() { 845 | return descriptor; 846 | } 847 | private static com.google.protobuf.Descriptors.FileDescriptor 848 | descriptor; 849 | static { 850 | java.lang.String[] descriptorData = { 851 | "\n\rMessage.proto\032\rCommand.proto\"H\n\013Messag" + 852 | "eBase\022\020\n\010clientId\030\001 \002(\t\022\031\n\003cmd\030\002 \002(\0162\014.C" + 853 | "ommandType\022\014\n\004data\030\003 \001(\tB$\n\031com.netty.co" + 854 | "mmon.protobufB\007Message" 855 | }; 856 | com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = 857 | new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { 858 | public com.google.protobuf.ExtensionRegistry assignDescriptors( 859 | com.google.protobuf.Descriptors.FileDescriptor root) { 860 | descriptor = root; 861 | return null; 862 | } 863 | }; 864 | com.google.protobuf.Descriptors.FileDescriptor 865 | .internalBuildGeneratedFileFrom(descriptorData, 866 | new com.google.protobuf.Descriptors.FileDescriptor[] { 867 | com.netty.common.protobuf.Command.getDescriptor(), 868 | }, assigner); 869 | internal_static_MessageBase_descriptor = 870 | getDescriptor().getMessageTypes().get(0); 871 | internal_static_MessageBase_fieldAccessorTable = new 872 | com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( 873 | internal_static_MessageBase_descriptor, 874 | new java.lang.String[] { "ClientId", "Cmd", "Data", }); 875 | com.netty.common.protobuf.Command.getDescriptor(); 876 | } 877 | 878 | // @@protoc_insertion_point(outer_class_scope) 879 | } 880 | -------------------------------------------------------------------------------- /src/main/java/com/netty/common/protobuf/Message.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | option java_package="com.netty.common.protobuf"; 4 | option java_outer_classname = "Message"; 5 | import "Command.proto"; 6 | 7 | message MessageBase { 8 | required string clientId = 1; 9 | required CommandType cmd = 2; 10 | optional string data = 3; 11 | } -------------------------------------------------------------------------------- /src/main/java/com/netty/common/util/ReflectionUtil.java: -------------------------------------------------------------------------------- 1 | package com.netty.common.util; 2 | 3 | import java.lang.reflect.Field; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | public class ReflectionUtil { 8 | /** 9 | * Used to generate map of class fields where key is field value and value is field name. 10 | */ 11 | public static Map generateMapOfValueNameInteger(Class clazz) { 12 | Map valuesName = new HashMap<>(); 13 | try { 14 | for (Field field : clazz.getFields()) { 15 | valuesName.put((Integer) field.get(int.class), field.getName()); 16 | } 17 | } catch (IllegalAccessException e) { 18 | e.printStackTrace(); 19 | } 20 | return valuesName; 21 | } 22 | 23 | /** 24 | * Used to generate map of class fields where key is field value and value is field name. 25 | */ 26 | public static Map generateMapOfValueNameShort(Class clazz) { 27 | Map valuesName = new HashMap<>(); 28 | try { 29 | for (Field field : clazz.getFields()) { 30 | if (field.getType().isPrimitive()) { 31 | valuesName.put((Short) field.get(short.class), field.getName()); 32 | } 33 | } 34 | } catch (IllegalAccessException e) { 35 | e.printStackTrace(); 36 | } 37 | return valuesName; 38 | } 39 | 40 | public static Object castTo(Class type, String value) { 41 | if (type == byte.class || type == Byte.class) { 42 | return Byte.valueOf(value); 43 | } 44 | if (type == short.class || type == Short.class) { 45 | return Short.valueOf(value); 46 | } 47 | if (type == int.class || type == Integer.class) { 48 | return Integer.valueOf(value); 49 | } 50 | if (type == long.class || type == Long.class) { 51 | return Long.valueOf(value); 52 | } 53 | if (type == boolean.class || type == Boolean.class) { 54 | return Boolean.valueOf(value); 55 | } 56 | return value; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/netty/server/Application.java: -------------------------------------------------------------------------------- 1 | package com.netty.server; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | import java.util.Set; 7 | 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.beans.factory.annotation.Qualifier; 10 | import org.springframework.beans.factory.annotation.Value; 11 | import org.springframework.boot.SpringApplication; 12 | import org.springframework.boot.autoconfigure.SpringBootApplication; 13 | import org.springframework.context.ConfigurableApplicationContext; 14 | import org.springframework.context.annotation.Bean; 15 | import org.springframework.context.annotation.ComponentScan; 16 | import org.springframework.context.annotation.Configuration; 17 | import org.springframework.context.annotation.Profile; 18 | import org.springframework.context.annotation.PropertySource; 19 | import io.netty.bootstrap.ServerBootstrap; 20 | import io.netty.channel.ChannelOption; 21 | import io.netty.channel.nio.NioEventLoopGroup; 22 | import io.netty.channel.socket.nio.NioServerSocketChannel; 23 | import io.netty.handler.logging.LogLevel; 24 | import io.netty.handler.logging.LoggingHandler; 25 | 26 | /** 27 | * 28 | * @author Shanqiang Ke 29 | * @version 1.0.0 30 | * @blog http://nosqlcoco.cnblogs.com 31 | * @since 2016-10-15 32 | */ 33 | @SpringBootApplication 34 | @ComponentScan(value = "com.netty.server") 35 | @PropertySource(value= "classpath:/application.properties") 36 | public class Application{ 37 | @Configuration 38 | @Profile("production") 39 | @PropertySource("classpath:/application.properties") 40 | static class Production 41 | { } 42 | 43 | @Configuration 44 | @Profile("local") 45 | @PropertySource({"classpath:/application.properties"}) 46 | static class Local 47 | { } 48 | public static void main(String[] args) throws Exception { 49 | ConfigurableApplicationContext context = SpringApplication.run(Application.class, args); 50 | TCPServer tcpServer = context.getBean(TCPServer.class); 51 | tcpServer.start(); 52 | } 53 | 54 | @Value("${tcp.port}") 55 | private int tcpPort; 56 | 57 | @Value("${boss.thread.count}") 58 | private int bossCount; 59 | 60 | @Value("${worker.thread.count}") 61 | private int workerCount; 62 | 63 | @Value("${so.keepalive}") 64 | private boolean keepAlive; 65 | 66 | @Value("${so.backlog}") 67 | private int backlog; 68 | 69 | @SuppressWarnings("unchecked") 70 | @Bean(name = "serverBootstrap") 71 | public ServerBootstrap bootstrap() { 72 | ServerBootstrap b = new ServerBootstrap(); 73 | b.group(bossGroup(), workerGroup()) 74 | .channel(NioServerSocketChannel.class) 75 | .handler(new LoggingHandler(LogLevel.DEBUG)) 76 | .childHandler(serverChannelInitializer); 77 | Map, Object> tcpChannelOptions = tcpChannelOptions(); 78 | Set> keySet = tcpChannelOptions.keySet(); 79 | for (@SuppressWarnings("rawtypes") ChannelOption option : keySet) { 80 | b.option(option, tcpChannelOptions.get(option)); 81 | } 82 | return b; 83 | } 84 | 85 | @Autowired 86 | @Qualifier("serverChannelInitializer") 87 | private ServerChannelInitializer serverChannelInitializer; 88 | 89 | @Bean(name = "tcpChannelOptions") 90 | public Map, Object> tcpChannelOptions() { 91 | Map, Object> options = new HashMap, Object>(); 92 | options.put(ChannelOption.SO_KEEPALIVE, keepAlive); 93 | options.put(ChannelOption.SO_BACKLOG, backlog); 94 | return options; 95 | } 96 | 97 | @Bean(name = "bossGroup", destroyMethod = "shutdownGracefully") 98 | public NioEventLoopGroup bossGroup() { 99 | return new NioEventLoopGroup(bossCount); 100 | } 101 | 102 | @Bean(name = "workerGroup", destroyMethod = "shutdownGracefully") 103 | public NioEventLoopGroup workerGroup() { 104 | return new NioEventLoopGroup(workerCount); 105 | } 106 | 107 | @Bean(name = "tcpSocketAddress") 108 | public InetSocketAddress tcpPort() { 109 | return new InetSocketAddress(tcpPort); 110 | } 111 | 112 | @Bean(name = "channelRepository") 113 | public ChannelRepository channelRepository() { 114 | return new ChannelRepository(); 115 | } 116 | } -------------------------------------------------------------------------------- /src/main/java/com/netty/server/ChannelRepository.java: -------------------------------------------------------------------------------- 1 | package com.netty.server; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.ConcurrentHashMap; 5 | 6 | import io.netty.channel.Channel; 7 | 8 | /** 9 | * Channel Manager 10 | * @author Ke Shanqiang 11 | * 12 | */ 13 | public class ChannelRepository { 14 | private final static Map channelCache = new ConcurrentHashMap(); 15 | 16 | public void put(String key, Channel value) { 17 | channelCache.put(key, value); 18 | } 19 | 20 | public Channel get(String key) { 21 | return channelCache.get(key); 22 | } 23 | 24 | public void remove(String key) { 25 | channelCache.remove(key); 26 | } 27 | 28 | public int size() { 29 | return channelCache.size(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/netty/server/ServerChannelInitializer.java: -------------------------------------------------------------------------------- 1 | package com.netty.server; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Qualifier; 7 | import org.springframework.stereotype.Component; 8 | 9 | import com.netty.common.protobuf.Message.MessageBase; 10 | import com.netty.server.handler.IdleServerHandler; 11 | 12 | import io.netty.channel.ChannelInboundHandlerAdapter; 13 | import io.netty.channel.ChannelInitializer; 14 | import io.netty.channel.ChannelPipeline; 15 | import io.netty.channel.socket.SocketChannel; 16 | import io.netty.handler.codec.protobuf.ProtobufDecoder; 17 | import io.netty.handler.codec.protobuf.ProtobufEncoder; 18 | import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; 19 | import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender; 20 | import io.netty.handler.timeout.IdleStateHandler; 21 | 22 | @Component 23 | @Qualifier("serverChannelInitializer") 24 | public class ServerChannelInitializer extends ChannelInitializer { 25 | private final static int READER_IDLE_TIME_SECONDS = 20;//读操作空闲20秒 26 | private final static int WRITER_IDLE_TIME_SECONDS = 20;//写操作空闲20秒 27 | private final static int ALL_IDLE_TIME_SECONDS = 40;//读写全部空闲40秒 28 | 29 | @Autowired 30 | @Qualifier("authServerHandler") 31 | private ChannelInboundHandlerAdapter authServerHandler; 32 | 33 | @Autowired 34 | @Qualifier("logicServerHandler") 35 | private ChannelInboundHandlerAdapter logicServerHandler; 36 | 37 | @Override 38 | protected void initChannel(SocketChannel socketChannel) throws Exception { 39 | ChannelPipeline p = socketChannel.pipeline(); 40 | 41 | p.addLast("idleStateHandler", new IdleStateHandler(READER_IDLE_TIME_SECONDS 42 | , WRITER_IDLE_TIME_SECONDS, ALL_IDLE_TIME_SECONDS, TimeUnit.SECONDS)); 43 | p.addLast("idleTimeoutHandler", new IdleServerHandler()); 44 | 45 | p.addLast(new ProtobufVarint32FrameDecoder()); 46 | p.addLast(new ProtobufDecoder(MessageBase.getDefaultInstance())); 47 | 48 | p.addLast(new ProtobufVarint32LengthFieldPrepender()); 49 | p.addLast(new ProtobufEncoder()); 50 | 51 | p.addLast("authServerHandler", authServerHandler); 52 | p.addLast("hearableServerHandler", logicServerHandler); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/netty/server/TCPServer.java: -------------------------------------------------------------------------------- 1 | package com.netty.server; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import javax.annotation.PreDestroy; 6 | 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.beans.factory.annotation.Qualifier; 9 | import org.springframework.stereotype.Component; 10 | 11 | import io.netty.bootstrap.ServerBootstrap; 12 | import io.netty.channel.Channel; 13 | 14 | @Component 15 | public class TCPServer { 16 | @Autowired 17 | @Qualifier("serverBootstrap") 18 | private ServerBootstrap serverBootstrap; 19 | 20 | @Autowired 21 | @Qualifier("tcpSocketAddress") 22 | private InetSocketAddress tcpPort; 23 | 24 | private Channel serverChannel; 25 | 26 | public void start() throws Exception { 27 | serverChannel = serverBootstrap.bind(tcpPort).sync().channel().closeFuture().sync().channel(); 28 | } 29 | 30 | @PreDestroy 31 | public void stop() throws Exception { 32 | serverChannel.close(); 33 | serverChannel.parent().close(); 34 | } 35 | 36 | public ServerBootstrap getServerBootstrap() { 37 | return serverBootstrap; 38 | } 39 | 40 | public void setServerBootstrap(ServerBootstrap serverBootstrap) { 41 | this.serverBootstrap = serverBootstrap; 42 | } 43 | 44 | public InetSocketAddress getTcpPort() { 45 | return tcpPort; 46 | } 47 | 48 | public void setTcpPort(InetSocketAddress tcpPort) { 49 | this.tcpPort = tcpPort; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/netty/server/handler/AuthServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.netty.server.handler; 2 | 3 | 4 | import org.apache.log4j.Logger; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Qualifier; 7 | import org.springframework.stereotype.Component; 8 | 9 | import com.netty.common.protobuf.Command.CommandType; 10 | import com.netty.common.protobuf.Message.MessageBase; 11 | import com.netty.server.ChannelRepository; 12 | 13 | import io.netty.channel.Channel; 14 | import io.netty.channel.ChannelHandler; 15 | import io.netty.channel.ChannelHandlerContext; 16 | import io.netty.channel.ChannelInboundHandlerAdapter; 17 | import io.netty.util.Attribute; 18 | import io.netty.util.AttributeKey; 19 | import io.netty.util.ReferenceCountUtil; 20 | 21 | /** 22 | * 连接认证Handler 23 | * 1. 连接成功后客户端发送CommandType.AUTH指令,Sever端验证通过后返回CommandType.AUTH_BACK指令 24 | * 2. 处理心跳指令 25 | * 3. 触发下一个Handler 26 | * @author Ke Shanqiang 27 | * 28 | */ 29 | @Component 30 | @Qualifier("authServerHandler") 31 | @ChannelHandler.Sharable 32 | public class AuthServerHandler extends ChannelInboundHandlerAdapter { 33 | public Logger log = Logger.getLogger(this.getClass()); 34 | private final AttributeKey clientInfo = AttributeKey.valueOf("clientInfo"); 35 | 36 | @Autowired 37 | @Qualifier("channelRepository") 38 | ChannelRepository channelRepository; 39 | 40 | @SuppressWarnings("deprecation") 41 | @Override 42 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 43 | MessageBase msgBase = (MessageBase)msg; 44 | String clientId = msgBase.getClientId(); 45 | 46 | Channel ch = channelRepository.get(clientId); 47 | if(null == ch){ 48 | ch = ctx.channel(); 49 | channelRepository.put(clientId, ch); 50 | } 51 | /*认证处理*/ 52 | if(msgBase.getCmd().equals(CommandType.AUTH)){ 53 | log.info("我是验证处理逻辑"); 54 | Attribute attr = ctx.attr(clientInfo); 55 | attr.set(clientId); 56 | channelRepository.put(clientId, ctx.channel()); 57 | 58 | ctx.writeAndFlush(createData(clientId, CommandType.AUTH_BACK, "This is response data").build()); 59 | 60 | }else if(msgBase.getCmd().equals(CommandType.PING)){ 61 | //处理ping消息 62 | ctx.writeAndFlush(createData(clientId, CommandType.PONG, "This is pong data").build()); 63 | 64 | }else{ 65 | if(ch.isOpen()){ 66 | //触发下一个handler 67 | ctx.fireChannelRead(msg); 68 | log.info("我进业务入处理逻辑"); 69 | } 70 | } 71 | ReferenceCountUtil.release(msg); 72 | } 73 | private MessageBase.Builder createData(String clientId, CommandType cmd,String data){ 74 | MessageBase.Builder msg = MessageBase.newBuilder(); 75 | msg.setClientId(clientId); 76 | msg.setCmd(cmd); 77 | msg.setData(data); 78 | return msg; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/netty/server/handler/IdleServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.netty.server.handler; 2 | 3 | import org.apache.log4j.Logger; 4 | import org.springframework.stereotype.Component; 5 | 6 | import io.netty.channel.ChannelHandlerContext; 7 | import io.netty.channel.ChannelInboundHandlerAdapter; 8 | import io.netty.handler.timeout.IdleState; 9 | import io.netty.handler.timeout.IdleStateEvent; 10 | /** 11 | * 连接空闲Handler 12 | */ 13 | @Component 14 | public class IdleServerHandler extends ChannelInboundHandlerAdapter { 15 | public Logger log = Logger.getLogger(this.getClass()); 16 | @Override 17 | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { 18 | if (evt instanceof IdleStateEvent) { 19 | IdleStateEvent event = (IdleStateEvent) evt; 20 | String type = ""; 21 | if (event.state() == IdleState.READER_IDLE) { 22 | type = "read idle"; 23 | } else if (event.state() == IdleState.WRITER_IDLE) { 24 | type = "write idle"; 25 | } else if (event.state() == IdleState.ALL_IDLE) { 26 | type = "all idle"; 27 | } 28 | log.debug(ctx.channel().remoteAddress()+"超时类型:" + type); 29 | } else { 30 | super.userEventTriggered(ctx, evt); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/netty/server/handler/LogicServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.netty.server.handler; 2 | 3 | import org.apache.log4j.Logger; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.beans.factory.annotation.Qualifier; 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.netty.common.protobuf.Message; 9 | import com.netty.common.protobuf.Command.CommandType; 10 | import com.netty.common.protobuf.Message.MessageBase; 11 | import com.netty.server.ChannelRepository; 12 | 13 | import io.netty.channel.ChannelFuture; 14 | import io.netty.channel.ChannelHandler; 15 | import io.netty.channel.ChannelHandlerContext; 16 | import io.netty.channel.ChannelInboundHandlerAdapter; 17 | import io.netty.util.Attribute; 18 | import io.netty.util.AttributeKey; 19 | import io.netty.util.ReferenceCountUtil; 20 | import io.netty.util.concurrent.Future; 21 | import io.netty.util.concurrent.GenericFutureListener; 22 | 23 | /** 24 | * 业务逻辑handler 25 | * @author Ke Shanqiang 26 | * 27 | */ 28 | @Component 29 | @Qualifier("logicServerHandler") 30 | @ChannelHandler.Sharable 31 | public class LogicServerHandler extends ChannelInboundHandlerAdapter{ 32 | public Logger log = Logger.getLogger(this.getClass()); 33 | private final AttributeKey clientInfo = AttributeKey.valueOf("clientInfo"); 34 | 35 | @Autowired 36 | @Qualifier("channelRepository") 37 | ChannelRepository channelRepository; 38 | 39 | @Override 40 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 41 | Message.MessageBase msgBase = (Message.MessageBase)msg; 42 | 43 | log.info(msgBase.getData()); 44 | 45 | ChannelFuture cf = ctx.writeAndFlush( 46 | MessageBase.newBuilder() 47 | .setClientId(msgBase.getClientId()) 48 | .setCmd(CommandType.UPLOAD_DATA_BACK) 49 | .setData("This is upload data back msg") 50 | .build() 51 | ); 52 | /* 上一条消息发送成功后,立马推送一条消息 */ 53 | cf.addListener(new GenericFutureListener>() { 54 | @Override 55 | public void operationComplete(Future future) throws Exception { 56 | if (future.isSuccess()){ 57 | ctx.writeAndFlush( 58 | MessageBase.newBuilder() 59 | .setClientId(msgBase.getClientId()) 60 | .setCmd(CommandType.PUSH_DATA) 61 | .setData("This is a push msg") 62 | .build() 63 | ); 64 | } 65 | } 66 | }); 67 | ReferenceCountUtil.release(msg); 68 | } 69 | 70 | @Override 71 | public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { 72 | 73 | } 74 | 75 | @SuppressWarnings("deprecation") 76 | @Override 77 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 78 | Attribute attr = ctx.attr(clientInfo); 79 | String clientId = attr.get(); 80 | log.error("Connection closed, client is " + clientId); 81 | cause.printStackTrace(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | tcp.port=8090 2 | boss.thread.count=2 3 | worker.thread.count=2 4 | so.keepalive=true 5 | so.backlog=100 6 | -------------------------------------------------------------------------------- /src/test/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nosqlcoco/springboot-netty-protobuf/5615a426f519adacd6b86ecb2eb0953ffb53fad1/src/test/.DS_Store -------------------------------------------------------------------------------- /src/test/java/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nosqlcoco/springboot-netty-protobuf/5615a426f519adacd6b86ecb2eb0953ffb53fad1/src/test/java/.DS_Store --------------------------------------------------------------------------------