作者 crossoverJie

:sparkles: Introducing new features.server ok

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