作者 crossoverJie

:sparkles: Introducing new features.server ok

@@ -29,6 +29,34 @@ @@ -29,6 +29,34 @@
29 <artifactId>spring-boot-starter-test</artifactId> 29 <artifactId>spring-boot-starter-test</artifactId>
30 <scope>test</scope> 30 <scope>test</scope>
31 </dependency> 31 </dependency>
  32 +
  33 + <dependency>
  34 + <groupId>org.springframework.boot</groupId>
  35 + <artifactId>spring-boot-configuration-processor</artifactId>
  36 + <optional>true</optional>
  37 + </dependency>
  38 +
  39 + <dependency>
  40 + <groupId>io.netty</groupId>
  41 + <artifactId>netty-all</artifactId>
  42 + <version>${netty.version}</version>
  43 + </dependency>
  44 +
  45 + <dependency>
  46 + <groupId>junit</groupId>
  47 + <artifactId>junit</artifactId>
  48 + </dependency>
  49 +
  50 + <dependency>
  51 + <groupId>com.alibaba</groupId>
  52 + <artifactId>fastjson</artifactId>
  53 + </dependency>
  54 +
  55 + <dependency>
  56 + <groupId>com.google.guava</groupId>
  57 + <artifactId>guava</artifactId>
  58 + </dependency>
  59 +
32 </dependencies> 60 </dependencies>
33 61
34 <build> 62 <build>
1 package com.crossoverjie.netty.action; 1 package com.crossoverjie.netty.action;
2 2
  3 +import io.netty.channel.ChannelFuture;
  4 +import org.slf4j.Logger;
  5 +import org.slf4j.LoggerFactory;
  6 +import org.springframework.beans.factory.annotation.Autowired;
  7 +import org.springframework.boot.CommandLineRunner;
3 import org.springframework.boot.SpringApplication; 8 import org.springframework.boot.SpringApplication;
4 import org.springframework.boot.autoconfigure.SpringBootApplication; 9 import org.springframework.boot.autoconfigure.SpringBootApplication;
5 10
@@ -7,10 +12,18 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -7,10 +12,18 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
7 * @author crossoverJie 12 * @author crossoverJie
8 */ 13 */
9 @SpringBootApplication 14 @SpringBootApplication
10 -public class Application { 15 +public class Application implements CommandLineRunner{
  16 +
  17 + private final static Logger LOGGER = LoggerFactory.getLogger(Application.class);
  18 +
11 19
12 public static void main(String[] args) { 20 public static void main(String[] args) {
13 SpringApplication.run(Application.class, args); 21 SpringApplication.run(Application.class, args);
  22 + LOGGER.info("启动成功");
14 } 23 }
15 24
  25 + @Override
  26 + public void run(String... args) throws Exception {
  27 +
  28 + }
16 } 29 }
  1 +package com.crossoverjie.netty.action.channel.init;
  2 +
  3 +import com.crossoverjie.netty.action.decoder.HeartbeatDecoder;
  4 +import com.crossoverjie.netty.action.handle.HeartBeatSimpleHandle;
  5 +import io.netty.channel.Channel;
  6 +import io.netty.channel.ChannelInitializer;
  7 +import io.netty.handler.timeout.IdleStateHandler;
  8 +
  9 +/**
  10 + * Function:
  11 + *
  12 + * @author crossoverJie
  13 + * Date: 17/05/2018 18:51
  14 + * @since JDK 1.8
  15 + */
  16 +public class HeartbeatInitializer extends ChannelInitializer<Channel> {
  17 + @Override
  18 + protected void initChannel(Channel ch) throws Exception {
  19 + ch.pipeline()
  20 + //五秒没有收到消息
  21 + .addLast(new IdleStateHandler(5, 0, 0))
  22 + .addLast(new HeartbeatDecoder())
  23 + .addLast(new HeartBeatSimpleHandle());
  24 + }
  25 +}
  1 +package com.crossoverjie.netty.action.decoder;
  2 +
  3 +import com.crossoverjie.netty.action.pojo.CustomProtocol;
  4 +import io.netty.buffer.ByteBuf;
  5 +import io.netty.channel.ChannelHandlerContext;
  6 +import io.netty.handler.codec.ByteToMessageDecoder;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * Function: 解码信息
  12 + *
  13 + * @author crossoverJie
  14 + * Date: 17/05/2018 18:34
  15 + * @since JDK 1.8
  16 + */
  17 +public class HeartbeatDecoder extends ByteToMessageDecoder {
  18 + @Override
  19 + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
  20 +
  21 + long header = in.readLong() ;
  22 + byte[] bytes = new byte[in.readableBytes()] ;
  23 + in.readBytes(bytes) ;
  24 + String content = new String(bytes) ;
  25 +
  26 + CustomProtocol customProtocol = new CustomProtocol() ;
  27 + customProtocol.setHeader(header);
  28 + customProtocol.setContent(content) ;
  29 + out.add(customProtocol) ;
  30 +
  31 + }
  32 +}
  1 +package com.crossoverjie.netty.action.handle;
  2 +
  3 +import com.crossoverjie.netty.action.pojo.CustomProtocol;
  4 +import io.netty.buffer.Unpooled;
  5 +import io.netty.channel.ChannelHandlerContext;
  6 +import io.netty.channel.SimpleChannelInboundHandler;
  7 +import io.netty.handler.timeout.IdleState;
  8 +import io.netty.handler.timeout.IdleStateEvent;
  9 +import io.netty.util.CharsetUtil;
  10 +import org.slf4j.Logger;
  11 +import org.slf4j.LoggerFactory;
  12 +
  13 +/**
  14 + * Function:
  15 + *
  16 + * @author crossoverJie
  17 + * Date: 17/05/2018 18:52
  18 + * @since JDK 1.8
  19 + */
  20 +public class HeartBeatSimpleHandle extends SimpleChannelInboundHandler<CustomProtocol> {
  21 +
  22 + private final static Logger LOGGER = LoggerFactory.getLogger(HeartBeatSimpleHandle.class);
  23 +
  24 +
  25 + @Override
  26 + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
  27 +
  28 + if (evt instanceof IdleStateEvent){
  29 + IdleStateEvent idleStateEvent = (IdleStateEvent) evt ;
  30 +
  31 + if (idleStateEvent.state() == IdleState.READER_IDLE){
  32 + LOGGER.info("已经5秒没有收到信息!");
  33 + //向客户端发送消息
  34 + CustomProtocol customProtocol = new CustomProtocol(12345L,"pong") ;
  35 + ctx.writeAndFlush(Unpooled.copiedBuffer(customProtocol.toString(), CharsetUtil.UTF_8)) ;
  36 + }
  37 +
  38 +
  39 + }
  40 +
  41 + super.userEventTriggered(ctx, evt);
  42 + }
  43 +
  44 + @Override
  45 + protected void channelRead0(ChannelHandlerContext ctx, CustomProtocol customProtocol) throws Exception {
  46 + LOGGER.info("customProtocol={}", customProtocol);
  47 +
  48 + //手动处理数据并返回
  49 + customProtocol.setHeader(customProtocol.getHeader() + 1000);
  50 + customProtocol.setContent(customProtocol.getContent() + 1000);
  51 + ctx.writeAndFlush(Unpooled.copiedBuffer(customProtocol.toString(), CharsetUtil.UTF_8));
  52 + }
  53 +}
  1 +package com.crossoverjie.netty.action.pojo;
  2 +
  3 +/**
  4 + * Function:
  5 + *
  6 + * @author crossoverJie
  7 + * Date: 17/05/2018 17:50
  8 + * @since JDK 1.8
  9 + */
  10 +public class CustomProtocol {
  11 +
  12 + private long header ;
  13 + private String content ;
  14 +
  15 + public long getHeader() {
  16 + return header;
  17 + }
  18 +
  19 + public void setHeader(long header) {
  20 + this.header = header;
  21 + }
  22 +
  23 + public String getContent() {
  24 + return content;
  25 + }
  26 +
  27 + public void setContent(String content) {
  28 + this.content = content;
  29 + }
  30 +
  31 + public CustomProtocol(long header, String content) {
  32 + this.header = header;
  33 + this.content = content;
  34 + }
  35 +
  36 + public CustomProtocol() {
  37 + }
  38 +
  39 + @Override
  40 + public String toString() {
  41 + return "CustomProtocol{" +
  42 + "header=" + header +
  43 + ", content='" + content + '\'' +
  44 + '}';
  45 + }
  46 +}
  1 +package com.crossoverjie.netty.action.server;
  2 +
  3 +import com.crossoverjie.netty.action.channel.init.HeartbeatInitializer;
  4 +import io.netty.bootstrap.ServerBootstrap;
  5 +import io.netty.channel.Channel;
  6 +import io.netty.channel.ChannelFuture;
  7 +import io.netty.channel.ChannelInitializer;
  8 +import io.netty.channel.EventLoopGroup;
  9 +import io.netty.channel.nio.NioEventLoopGroup;
  10 +import io.netty.channel.socket.nio.NioServerSocketChannel;
  11 +import io.netty.handler.timeout.IdleStateHandler;
  12 +import org.springframework.beans.factory.annotation.Configurable;
  13 +import org.springframework.context.annotation.Bean;
  14 +import org.springframework.context.annotation.Configuration;
  15 +
  16 +import java.net.InetSocketAddress;
  17 +
  18 +/**
  19 + * Function:
  20 + *
  21 + * @author crossoverJie
  22 + * Date: 21/05/2018 00:30
  23 + * @since JDK 1.8
  24 + */
  25 +@Configuration
  26 +public class HeartBeatServer {
  27 +
  28 + @Bean
  29 + public ChannelFuture buildFuture() {
  30 +
  31 + EventLoopGroup boss = new NioEventLoopGroup();
  32 + EventLoopGroup work = new NioEventLoopGroup();
  33 +
  34 + try {
  35 +
  36 + ServerBootstrap bootstrap = new ServerBootstrap()
  37 + .group(boss, work)
  38 + .channel(NioServerSocketChannel.class)
  39 + .localAddress(new InetSocketAddress(11211))
  40 + .childHandler(new HeartbeatInitializer());
  41 +
  42 + ChannelFuture future = bootstrap.bind().sync();
  43 + future.channel().closeFuture().sync();
  44 + return future;
  45 + } catch (InterruptedException e) {
  46 + } finally {
  47 + }
  48 +
  49 + return null;
  50 + }
  51 +}
1 # web port 1 # web port
2 -server.port=8081  
  2 +server.port=8081
  3 +
  4 +netty.server.port=11211
  5 +
  6 +logging.level.root=debug
@@ -10,6 +10,14 @@ @@ -10,6 +10,14 @@
10 <description>Spring Boot</description> 10 <description>Spring Boot</description>
11 11
12 12
  13 + <properties>
  14 + <junit.version>4.11</junit.version>
  15 + <netty.version>4.1.21.Final</netty.version>
  16 + <logback.version>1.0.13</logback.version>
  17 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  18 + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  19 + </properties>
  20 +
13 <parent> 21 <parent>
14 <groupId>org.springframework.boot</groupId> 22 <groupId>org.springframework.boot</groupId>
15 <artifactId>spring-boot-starter-parent</artifactId> 23 <artifactId>spring-boot-starter-parent</artifactId>
@@ -21,4 +29,33 @@ @@ -21,4 +29,33 @@
21 <module>netty-action-heartbeat</module> 29 <module>netty-action-heartbeat</module>
22 </modules> 30 </modules>
23 31
  32 +
  33 + <dependencyManagement>
  34 + <dependencies>
  35 + <dependency>
  36 + <groupId>io.netty</groupId>
  37 + <artifactId>netty-all</artifactId>
  38 + <version>${netty.version}</version>
  39 + </dependency>
  40 +
  41 + <dependency>
  42 + <groupId>junit</groupId>
  43 + <artifactId>junit</artifactId>
  44 + <version>${junit.version}</version>
  45 + </dependency>
  46 +
  47 + <dependency>
  48 + <groupId>com.alibaba</groupId>
  49 + <artifactId>fastjson</artifactId>
  50 + <version>1.1.40</version>
  51 + </dependency>
  52 +
  53 + <dependency>
  54 + <groupId>com.google.guava</groupId>
  55 + <artifactId>guava</artifactId>
  56 + <version>19.0</version>
  57 + </dependency>
  58 + </dependencies>
  59 + </dependencyManagement>
  60 +
24 </project> 61 </project>