本文主要是介绍使用 Netty 实现 IM 聊天贼简单,看不懂就锤爆哪吒的狗头~(上),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
- 1. 概述
- 2. 构建 Netty 服务端与客户端
- 3. 通信协议
- 4. 消息分发
- 5. 断开重连
- 6. 心跳机制与空闲检测
- 7. 认证逻辑
- 8. 单聊逻辑
- 9. 群聊逻辑
- 666. 彩蛋
本文在提供完整代码示例 转发+关注 私信我【源码】直接免费分享给你
原创不易,给点个 哪吒 嘿,一起冲鸭!
1. 概述
“
Netty 是一个 Java 开源框架。
Netty 提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
也就是说,Netty 是一个基于 NIO 的客户、服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。
Netty 相当简化和流线化了网络应用的编程开发过程,例如,TCP 和 UDP 的 Socket 服务开发。
下面,我们来新建三个项目,如下图所示:
三个项目
- lab-67-netty-demo-server 项目:搭建 Netty 服务端。
- lab-67-netty-demo-client 项目:搭建 Netty 客户端。
- lab-67-netty-demo-common 项目:提供 Netty 的基础封装,提供消息的编解码、分发的功能。
另外,我们也会提供 Netty 常用功能的示例:
- 心跳机制,实现服务端对客户端的存活检测。
- 断线重连,实现客户端对服务端的重新连接。
不哔哔,直接开干。
“
友情提示:可能会胖友担心,没有 Netty 基础是不是无法阅读本文?!
艿艿的想法,看!就硬看,按照代码先自己能搭建一下哈~文末,艿艿会提供一波 Netty 基础入门的文章。
2. 构建 Netty 服务端与客户端
本小节,我们先来使用 Netty 构建服务端与客户端的核心代码,让胖友对项目的代码有个初始的认知。
2.1 构建 Netty 服务端
创建 lab-67-netty-demo-server 项目,搭建 Netty 服务端。如下图所示:
项目结构
下面,我们只会暂时看看 server 包下的代码,避免信息量过大,击穿胖友的秃头。
2.1.1 NettyServer
创建 NettyServer 类,Netty 服务端。代码如下:
@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 {
// <2.1> 创建 ServerBootstrap 对象,用于 Netty Server 启动
ServerBootstrap bootstrap = new ServerBootstrap();
// <2.2> 设置 ServerBootstrap 的各种属性
bootstrap.group(bossGroup, workerGroup) // <2.2.1> 设置两个 EventLoopGroup 对象
.channel(NioServerSocketChannel.class) // <2.2.2> 指定 Channel 为服务端 NioServerSocketChannel
.localAddress(new InetSocketAddress(port)) // <2.2.3> 设置 Netty Server 的端口
.option(ChannelOption.SO_BACKLOG, 1024) // <2.2.4> 服务端 accept 队列的大小
.childOption(ChannelOption.SO_KEEPALIVE, true) // <2.2.5> TCP Keepalive 机制,实现 TCP 层级的心跳保活功能
.childOption(ChannelOption.TCP_NODELAY, true) // <2.2.6> 允许较小的数据包的发送,降低延迟
.childHandler(nettyServerHandlerInitializer);
// <2> 绑定端口,并同步等待成功,即启动服务端
ChannelFuture future = bootstrap.bind().sync();
if (future.isSuccess()) {
channel = future.channel();
logger.info("[start][Netty Server 启动在 {} 端口]", port);
}
} /**
* 关闭 Netty Server
*/
@PreDestroy
public void shutdown() {
// <3.1> 关闭 Netty Server
if (channel != null) {
channel.close();
}
// <3.2> 优雅关闭两个 EventLoopGroup 对象
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}}
① 在类上,添加 @Component 注解,把 NettyServer 的创建交给 Spring 管理。
- port 属性,读取 application.yml 配置文件的 netty.port 配置项。
- #start() 方法,添加 @PostConstruct 注解,启动 Netty 服务器。
- #shutdown() 方法,添加 @PreDestroy 注解,关闭 Netty 服务器。
② 我们来详细看看 #start() 方法的代码,如何实现 Netty Server 的启动。
<2.1> 处,创建 ServerBootstrap 类,Netty 提供的服务器的启动类,方便我们初始化 Server。
<2.2> 处,设置 ServerBootstrap 的各种属性。
“
友情提示:这里涉及较多 Netty 组件的知识,艿艿先以简单的语言描述,后续胖友在文末的 Netty 基础入门的文章,补充学噢。
<2.2.1> 处,调用 #group(EventLoopGroup parentGroup, EventLoopGroup childGroup) 方法,设置使用 bossGroup 和 workerGroup。其中:
- bossGroup 属性:Boss 线程组,用于服务端接受客户端的连接。
- workerGroup 属性:Worker 线程组,用于服务端接受客户端的数据读写。
“
Netty 采用的是多 Reactor 多线程的模型,服务端可以接受更多客户端的数据读写的能力。原因是:
创建专门用于接受客户端连接的 bossGroup 线程组,避免因为已连接的客户端的数据读写频繁,影响新的客户端的连接。
创建专门用于接收客户端读写的 workerGroup 线程组,多个线程进行客户端的数据读写,可以支持更多客户端。
课后习题:感兴趣的胖友,后续可以看看《【NIO 系列】——之 Reactor 模型》文章。
<2.2.2> 处,调用 #channel(Class<? extends C> channelClass) 方法,设置使用 NioServerSocketChannel 类,它是 Netty 定义的 NIO 服务端 TCP Socket 实现类。
<2.2.3> 处,调用 #localAddress(SocketAddress localAddress) 方法,设置服务端的端口。
<
这篇关于使用 Netty 实现 IM 聊天贼简单,看不懂就锤爆哪吒的狗头~(上)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!