SpringBoot整合Netty
文章目录
1 搭建项目
1.1 项目目录
1.2 pom文件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.70.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
</dependencies>
2. 构建Netty服务
2.1 NettyServer
package com.xzq.server;
@Component
@Data
public class NettyServer {
private Logger logger = LoggerFactory.getLogger(NettyServer.class);
//NIO线程组
private NioEventLoopGroup boos = new NioEventLoopGroup();
private NioEventLoopGroup worker = new NioEventLoopGroup();
private Channel channel;
public ChannelFuture lister(int port) {
ChannelFuture f = null;
try {
ServerBootstrap b = new ServerBootstrap()
.group(boos, worker)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 128)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
//采用分割符解决半包黏包
ch.pipeline().addLast(new LineBasedFrameDecoder(1024));
//字符串的编解码器
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
//添加自己的消息处理器
ch.pipeline().addLast(new ServerHandler());
}
});
f = b.bind(port).sync();
channel= f.channel();
} catch (Exception e) {
e.printStackTrace();
}finally {
if (f != null && f.isSuccess()) {
logger.info("Netty 服务端启动成功.....");
}else{
logger.info("Netty 服务端启动失败.....");
}
}
return f;
}
//销毁方法
public void destroy() {
if (channel==null){return;}
channel.close();
worker.shutdownGracefully();
boos.shutdownGracefully();
}
}
2.1 NettyHandler
package com.xzq.server;
public class ServerHandler extends ChannelInboundHandlerAdapter {
private Logger logger = LoggerFactory.getLogger(ServerHandler.class);
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof String) {
String strMsg = (String) msg;
logger.info("服务端收到消息: " + msg);
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
logger.info("连接建立.....");
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
logger.info("连接断开");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
logger.error("连接异常: \r\n" + cause);
}
}
3. 整合springboot
3.1 application.yml
netty:
port: 9999
3.2 启动类
package com.xzq;
import com.xzq.server.NettyServer;
import io.netty.channel.ChannelFuture;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @Author xzq
* @Description //TODO
* @Date 2021/11/22 9:20
* @Version 1.0.0
**/
@SpringBootApplication
public class App implements CommandLineRunner {
@Value("${netty.port}")
private Integer port;
@Autowired
private NettyServer nettyServer;
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Override
public void run(String... args) throws Exception {
ChannelFuture channelFuture = nettyServer.lister(port);
//增加虚拟机钩子函数
Runtime.getRuntime().addShutdownHook(new Thread(()->{
nettyServer.destroy();
}));
channelFuture.channel().closeFuture().channel();
}
}
4. 测试
发送TCP请求