如何用Netty写一个IM聊天系统

什么是Netty

简单概括,Netty是一个Java开源框架,是一个异步的、基于事件驱动的网络应用框架,用以快速开发高性能、高可靠的网络IO程序。Netty 本质是一个 NIO 框架,适用于服务器通讯相关的多种应用场景。

准备

能够很好的理解这个project,最好对SpringBoot、Netty、长连接及im即时通讯有相关的提前了解。

目录结构及源码

项目源码:github项目源码,有任何问题也欢迎交流讨论

项目基于gradle,目录如下

  • api:Netty服务端
  • client:Netty客户端
  • logic:业务逻辑,提供Netty的基础封装,api与client复用
服务端启动类:NettyImDemoApiApplicationContext
客户端启动类:NettyImDemoClientApplicationContext

Netty服务端构建

Netty服务端两个核心类:
NettyServer服务端引导类

public class NettyServer {

    /**
     * 读取application.yml配置
     */
    @Value("${netty.port}")
    private Integer port;
    /**
     * Netty Server服务端Channel
     */
    private Channel channel;

    private EventLoopGroup bossGroup = new NioEventLoopGroup();

    private EventLoopGroup workerGroup = new NioEventLoopGroup();

    private final NettyServerHandlerInitializer nettyServerHandlerInitializer;

    public NettyServer(NettyServerHandlerInitializer nettyServerHandlerInitializer) {
        this.nettyServerHandlerInitializer = nettyServerHandlerInitializer;
    }

    /**
     * 启动Netty Server
     * @throws InterruptedException
     */
    @PostConstruct
    public void start() throws InterruptedException {
        // 创建引导,用于netty启动
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        // 在创建ServerBootstrap类实例前,先创建两个EventLoopGroup,它们实际上是两个独立的Reactor线程池
        // Netty默认线程模型是「主从Reactor多线程模型」,
        serverBootstrap.group(bossGroup, workerGroup)
                // 指定 Channel为服务端NioServerSocketChannel
                .channel(NioServerSocketChannel.class)
                .localAddress(new InetSocketAddress(port))
                // 设置服务端accept队列大小
                .option(ChannelOption.SO_BACKLOG, 1024)
                // TCP Keepalive 机制,实现 TCP 层级的心跳保活功能
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                // 允许较小的数据包的发送,降低延迟
                .childOption(ChannelOption.TCP_NODELAY, true)
                // 设置客户端连接上来的 Channel 的处理器为 NettyServerHandlerInitializer
                // 在每一个客户端与服务端建立完成连接时,服务端会创建一个Channel与之对应, NettyServerHandlerInitializer会进行执行initChannel(Channel c) 方法,进行自定义的初始化
                .childHandler(nettyServerHandlerInitializer);
        // 绑定端口,并同步等待成功,即启动Netty Server服务端
        ChannelFuture future = serverBootstrap.bind().sync();
        if (future.isSuccess()) {
            // 启动成功,获取Channel引用
            channel = future.channel();
            log.info("start Netty Server port {}", port);
        }
    }

    /**
     * 关闭 Netty Server
     */
    @PreDestroy
    public void gracefulShutdown() {
        if (Objects.nonNull(channel)) {
        
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值