• 1. 概述
  • 2. 构建 Netty 服务端与客户端
  • 3. 通信协议
  • 4. 消息分发
  • 5. 断开重连
  • 6. 心跳机制与空闲检测
  • 7. 认证逻辑
  • 8. 单聊逻辑
  • 9. 群聊逻辑
  • 666. 彩蛋

本文在提供完整代码示例,可见 https://github.com/YunaiV/SpringBoot-Labs 的 lab-67 目录。

原创不易,给点个 Star 嘿,一起冲鸭!

1. 概述

在《芋道 Spring Boot WebSocket 入门》文章中,我们使用 WebSocket 实现了一个简单的 IM 功能,支持身份认证、私聊消息、群聊消息。

然后就有胖友私信艿艿,希望使用纯 Netty 实现一个类似的功能。良心的艿艿,当然不会给她发红人卡,因此就有了本文。可能有胖友不知道 Netty 是什么,这里简单介绍下:

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();
    }

}

©著作权归作者所有:来自51CTO博客作者mb5ff80520dfa04的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 使用Python开发客户端和服务端程序 理解应用层协议和表示层
  2. 客户端用不着的数据结构之并查集
  3. 1.5 万 Star!界面酷炫、简单易用的数据库开源客户端
  4. 分享PHP5.5在windows安装使用memcached服务端的方法
  5. 关于php使用thrift做服务端开发的那些事
  6. 使用PHP来获取客户端和服务端IP
  7. php实时推送系统消息给客户端的原理及详解
  8. 干掉Navicat!MySQL官方客户端到底行不行?
  9. Github标星 8K+,免费又好用的Redis客户端工具!

随机推荐

  1. android 抽屉效果
  2. 如何进入Android adb shell 命令行模式
  3. mac 下 android studio 识别不出真机
  4. Layout属性介绍
  5. 在android中实现动态跑动的图表实现方法
  6. 理解Android的手势识别
  7. android之wifi体系架构源码流程分析
  8. Android 混淆打包
  9. android中获取当前程序路径
  10. Android中ListView中显示图片和文本