mirror of
https://gitee.com/yudaocode/SpringBoot-Labs.git
synced 2026-09-03 05:53:54 +08:00
开始 Netty 入门示例
This commit is contained in:
56
lab-67/lab-67-netty-demo/lab-67-netty-demo-client/pom.xml
Normal file
56
lab-67/lab-67-netty-demo/lab-67-netty-demo-client/pom.xml
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>lab-67-netty-demo</artifactId>
|
||||
<groupId>cn.iocoder.springboot.labs</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>lab-67-netty-demo-client</artifactId>
|
||||
|
||||
<properties>
|
||||
<!-- 依赖相关配置 -->
|
||||
<spring.boot.version>2.2.4.RELEASE</spring.boot.version>
|
||||
<!-- 插件相关配置 -->
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<!-- 实现对 Spring MVC 的自动化配置 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Netty 依赖 -->
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.50.Final</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入 netty-demo-common 封装 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.springboot.labs</groupId>
|
||||
<artifactId>lab-67-netty-demo-common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,4 @@
|
||||
package cn.iocoder.springboot.lab67.nettyclientdemo;
|
||||
|
||||
public class NettyClientApplication {
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package cn.iocoder.springboot.lab67.nettyclientdemo.config;
|
||||
|
||||
import cn.iocoder.springboot.lab67.nettycommondemo.dispacher.MessageDispatcher;
|
||||
import cn.iocoder.springboot.lab67.nettycommondemo.dispacher.MessageHandlerContainer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class NettyClientConfig {
|
||||
|
||||
@Bean
|
||||
public MessageDispatcher messageDispatcher() {
|
||||
return new MessageDispatcher();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageHandlerContainer messageHandlerContainer() {
|
||||
return new MessageHandlerContainer();
|
||||
}
|
||||
|
||||
}
|
||||
55
lab-67/lab-67-netty-demo/lab-67-netty-demo-common/pom.xml
Normal file
55
lab-67/lab-67-netty-demo/lab-67-netty-demo-common/pom.xml
Normal file
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>lab-67-netty-demo</artifactId>
|
||||
<groupId>cn.iocoder.springboot.labs</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>lab-67-netty-demo-common</artifactId>
|
||||
|
||||
<properties>
|
||||
<!-- 插件相关配置 -->
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- Netty 依赖 -->
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.50.Final</version>
|
||||
</dependency>
|
||||
|
||||
<!-- FastJSON 依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.71</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入 Spring 相关依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>5.2.5.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>5.2.5.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入 SLF4J 依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.30</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,41 @@
|
||||
package cn.iocoder.springboot.lab67.nettycommondemo.codec;
|
||||
|
||||
public class Invocation {
|
||||
|
||||
/**
|
||||
* 类型 - 心跳请求
|
||||
*/
|
||||
public static final String TYPE_HEARTBEAT_REQUEST = "HEARTBEAT_REQUEST";
|
||||
/**
|
||||
* 类型 - 心跳响应
|
||||
*/
|
||||
public static final String TYPE_HEARTBEAT_RESPONSE = "HEARTBEAT_RESPONSE";
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private String type;
|
||||
/**
|
||||
* 消息
|
||||
*/
|
||||
private String message;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Invocation setType(String type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Invocation setMessage(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package cn.iocoder.springboot.lab67.nettycommondemo.codec;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
import io.netty.handler.codec.CorruptedFrameException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class InvocationDecoder extends ByteToMessageDecoder {
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
|
||||
// 标记当前读取位置
|
||||
in.markReaderIndex();
|
||||
// 判断是否能够读取 length 长度
|
||||
if (in.readableBytes() <= 4) {
|
||||
return;
|
||||
}
|
||||
// 读取长度
|
||||
int length = in.readInt();
|
||||
if (length < 0) {
|
||||
throw new CorruptedFrameException("negative length: " + length);
|
||||
}
|
||||
// 如果 message 不够可读,则退回到原读取位置
|
||||
if (in.readableBytes() < length) {
|
||||
in.resetReaderIndex();
|
||||
return;
|
||||
}
|
||||
// 读取内容
|
||||
ByteBuf byteBuf = in.readRetainedSlice(length);
|
||||
// 解析成 Invocation
|
||||
byte[] content = byteBuf.array();
|
||||
Invocation invocation = JSON.parseObject(content, Invocation.class);
|
||||
out.add(invocation);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.springboot.lab67.nettycommondemo.codec;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
|
||||
public class InvocationEncoder extends MessageToByteEncoder<Invocation> {
|
||||
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext ctx, Invocation invocation, ByteBuf out) {
|
||||
// 将 Invocation 转换成 byte[] 数组
|
||||
byte[] content = JSON.toJSONBytes(invocation);
|
||||
// 写入 length
|
||||
out.writeInt(content.length);
|
||||
// 写入内容
|
||||
out.writeBytes(content);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package cn.iocoder.springboot.lab67.nettycommondemo.dispacher;
|
||||
|
||||
public interface Message {
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package cn.iocoder.springboot.lab67.nettycommondemo.dispacher;
|
||||
|
||||
import cn.iocoder.springboot.lab67.nettycommondemo.codec.Invocation;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public class MessageDispatcher extends SimpleChannelInboundHandler<Invocation> {
|
||||
|
||||
@Autowired
|
||||
private MessageHandlerContainer messageHandlerContainer;
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, Invocation invocation) {
|
||||
// 获得 type 对应的 MessageHandler 处理器
|
||||
MessageHandler messageHandler = messageHandlerContainer.getMessageHandler(invocation.getType());
|
||||
// 解析消息
|
||||
Class<? extends Message> messageClass = MessageHandlerContainer.getMessageClass(messageHandler);
|
||||
Message message = JSON.parseObject(invocation.getMessage(), messageClass);
|
||||
// 执行逻辑
|
||||
// noinspection unchecked
|
||||
messageHandler.execute(ctx.channel(), message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.springboot.lab67.nettycommondemo.dispacher;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
public interface MessageHandler<T extends Message> {
|
||||
|
||||
/**
|
||||
* 执行处理消息
|
||||
*
|
||||
* @param channel 通道
|
||||
* @param message 消息
|
||||
*/
|
||||
void execute(Channel channel, T message);
|
||||
|
||||
/**
|
||||
* @return 消息类型,即每个 Message 实现类上的 TYPE 静态字段
|
||||
*/
|
||||
String getType();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package cn.iocoder.springboot.lab67.nettycommondemo.dispacher;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.aop.framework.AopProxyUtils;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class MessageHandlerContainer implements InitializingBean {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
/**
|
||||
* 消息类型与 MessageHandler 的映射
|
||||
*/
|
||||
private final Map<String, MessageHandler> handlers = new HashMap<>();
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
// 通过 ApplicationContext 获得所有 MessageHandler Bean
|
||||
applicationContext.getBeansOfType(MessageHandler.class).values() // 获得所有 MessageHandler Bean
|
||||
.forEach(messageHandler -> handlers.put(messageHandler.getType(), messageHandler)); // 添加到 handlers 中
|
||||
logger.info("[afterPropertiesSet][消息处理器数量:{}]", handlers.size());
|
||||
}
|
||||
|
||||
protected MessageHandler getMessageHandler(String type) {
|
||||
MessageHandler handler = handlers.get(type);
|
||||
if (handler == null) {
|
||||
throw new IllegalArgumentException(String.format("类型(%s) 找不到匹配的 MessageHandler 处理器", type));
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
public static Class<? extends Message> getMessageClass(MessageHandler handler) {
|
||||
// 获得 Bean 对应的 Class 类名。因为有可能被 AOP 代理过。
|
||||
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(handler);
|
||||
// 获得接口的 Type 数组
|
||||
Type[] interfaces = targetClass.getGenericInterfaces();
|
||||
Class<?> superclass = targetClass.getSuperclass();
|
||||
while ((Objects.isNull(interfaces) || 0 == interfaces.length) && Objects.nonNull(superclass)) { // 此处,是以父类的接口为准
|
||||
interfaces = superclass.getGenericInterfaces();
|
||||
superclass = targetClass.getSuperclass();
|
||||
}
|
||||
if (Objects.nonNull(interfaces)) {
|
||||
// 遍历 interfaces 数组
|
||||
for (Type type : interfaces) {
|
||||
// 要求 type 是泛型参数
|
||||
if (type instanceof ParameterizedType) {
|
||||
ParameterizedType parameterizedType = (ParameterizedType) type;
|
||||
// 要求是 MessageHandler 接口
|
||||
if (Objects.equals(parameterizedType.getRawType(), MessageHandler.class)) {
|
||||
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
|
||||
// 取首个元素
|
||||
if (Objects.nonNull(actualTypeArguments) && actualTypeArguments.length > 0) {
|
||||
return (Class<Message>) actualTypeArguments[0];
|
||||
} else {
|
||||
throw new IllegalStateException(String.format("类型(%s) 获得不到消息类型", handler));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException(String.format("类型(%s) 获得不到消息类型", handler));
|
||||
}
|
||||
|
||||
}
|
||||
56
lab-67/lab-67-netty-demo/lab-67-netty-demo-server/pom.xml
Normal file
56
lab-67/lab-67-netty-demo/lab-67-netty-demo-server/pom.xml
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>lab-67-netty-demo</artifactId>
|
||||
<groupId>cn.iocoder.springboot.labs</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>lab-67-netty-demo-server</artifactId>
|
||||
|
||||
<properties>
|
||||
<!-- 依赖相关配置 -->
|
||||
<spring.boot.version>2.2.4.RELEASE</spring.boot.version>
|
||||
<!-- 插件相关配置 -->
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring Boot 基础依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Netty 依赖 -->
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.50.Final</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入 netty-demo-common 封装 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.springboot.labs</groupId>
|
||||
<artifactId>lab-67-netty-demo-common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,13 @@
|
||||
package cn.iocoder.springboot.lab67.nettyserverdemo;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class NettyServerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(NettyServerApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package cn.iocoder.springboot.lab67.nettyserverdemo.config;
|
||||
|
||||
import cn.iocoder.springboot.lab67.nettycommondemo.dispacher.MessageDispatcher;
|
||||
import cn.iocoder.springboot.lab67.nettycommondemo.dispacher.MessageHandlerContainer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class NettyServerConfig {
|
||||
|
||||
@Bean
|
||||
public MessageDispatcher messageDispatcher() {
|
||||
return new MessageDispatcher();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageHandlerContainer messageHandlerContainer() {
|
||||
return new MessageHandlerContainer();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package cn.iocoder.springboot.lab67.nettyserverdemo.server;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
@Component
|
||||
public class NettyServer {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Value("${netty.port}")
|
||||
private Integer port;
|
||||
|
||||
@Autowired
|
||||
private NettyServerHandlerInitializer nettyServerHandlerInitializer;
|
||||
|
||||
/**
|
||||
* boss 线程组,用于服务端接受客户端的连接
|
||||
*/
|
||||
private EventLoopGroup bossGroup = new NioEventLoopGroup();
|
||||
/**
|
||||
* worker 线程组,用于服务端接受客户端的数据读写
|
||||
*/
|
||||
private EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||
/**
|
||||
* Netty Server Channel
|
||||
*/
|
||||
private Channel channel;
|
||||
|
||||
/**
|
||||
* 启动 Netty Server
|
||||
*/
|
||||
@PostConstruct
|
||||
public void start() throws InterruptedException {
|
||||
// 创建 ServerBootstrap 对象,用于 Netty Server 启动
|
||||
ServerBootstrap bootstrap = new ServerBootstrap();
|
||||
bootstrap.group(bossGroup, workerGroup) // 设置两个 EventLoopGroup 对象
|
||||
.channel(NioServerSocketChannel.class) // 指定 Channel 为服务端 NioServerSocketChannel
|
||||
.localAddress(new InetSocketAddress(port)) // 设置 Netty Server 的端口
|
||||
.option(ChannelOption.SO_BACKLOG, 1024) // 服务端 accept 队列的大小
|
||||
.childOption(ChannelOption.SO_KEEPALIVE, true) // TCP Keepalive 机制,实现 TCP 层级的心跳保活功能
|
||||
.childOption(ChannelOption.TCP_NODELAY, true) // 允许较小的数据包的发送,降低延迟
|
||||
.childHandler(nettyServerHandlerInitializer);
|
||||
// 绑定端口,并同步等待成功,即启动服务端
|
||||
ChannelFuture future = bootstrap.bind().sync();
|
||||
if (future.isSuccess()) {
|
||||
channel = future.channel();
|
||||
logger.info("[start][Netty Server 启动在 {} 端口]", port);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭 Netty Server
|
||||
*/
|
||||
@PreDestroy
|
||||
public void shutdown() {
|
||||
// 关闭 Netty Server
|
||||
if (channel != null) {
|
||||
channel.close();
|
||||
}
|
||||
// 优雅关闭两个 EventLoopGroup 对象
|
||||
bossGroup.shutdownGracefully();
|
||||
workerGroup.shutdownGracefully();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package cn.iocoder.springboot.lab67.nettyserverdemo.server;
|
||||
|
||||
import cn.iocoder.springboot.lab67.nettycommondemo.codec.InvocationDecoder;
|
||||
import cn.iocoder.springboot.lab67.nettycommondemo.codec.InvocationEncoder;
|
||||
import cn.iocoder.springboot.lab67.nettycommondemo.dispacher.MessageDispatcher;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class NettyServerHandlerInitializer extends ChannelInitializer<Channel> {
|
||||
|
||||
@Autowired
|
||||
private MessageDispatcher messageDispatcher;
|
||||
|
||||
@Override
|
||||
protected void initChannel(Channel ch) throws Exception {
|
||||
ch.pipeline()
|
||||
// 空闲检测
|
||||
// .addLast(new ServerIdleStateHandler())
|
||||
// 编码器
|
||||
.addLast(new InvocationEncoder())
|
||||
// 解码器
|
||||
.addLast(new InvocationDecoder())
|
||||
// 服务端处理器
|
||||
.addLast(messageDispatcher)
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
netty:
|
||||
port: 8888 # Netty Server 端口
|
||||
21
lab-67/lab-67-netty-demo/pom.xml
Normal file
21
lab-67/lab-67-netty-demo/pom.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>lab-67</artifactId>
|
||||
<groupId>cn.iocoder.springboot.labs</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>lab-67-netty-demo</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>lab-67-netty-demo-server</module>
|
||||
<module>lab-67-netty-demo-client</module>
|
||||
<module>lab-67-netty-demo-common</module>
|
||||
</modules>
|
||||
|
||||
|
||||
</project>
|
||||
19
lab-67/pom.xml
Normal file
19
lab-67/pom.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>labs-parent</artifactId>
|
||||
<groupId>cn.iocoder.springboot.labs</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>lab-67</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>lab-67-netty-demo</module>
|
||||
</modules>
|
||||
|
||||
|
||||
</project>
|
||||
Reference in New Issue
Block a user