初识Netty

本文介绍了如何在SpringBoot项目中使用Maven引入Netty库,创建一个服务器端处理程序,包括配置NioEventLoopGroup、ServerBootstrap、自定义ChannelInitializer和NettyServiceHandler,以及使用SpringCommandLineRunner实现启动和关闭Netty服务。
摘要由CSDN通过智能技术生成
  • maven依赖 (netty)

     <dependency>
    	  <groupId>io.netty</groupId>
    	  <artifactId>netty-all</artifactId>
    	  <version>4.1.36.Final</version>
     </dependency>
    
  • server端的处理

    • 基础配置 [有些参数可以用yml文件配置 更加灵活]

      package com.kyrie.netty.server;
      
      import io.netty.bootstrap.ServerBootstrap;
      import io.netty.channel.*;
      import io.netty.channel.nio.NioEventLoopGroup;
      import io.netty.channel.socket.SocketChannel;
      import io.netty.channel.socket.nio.NioServerSocketChannel;
      import io.netty.handler.codec.string.StringDecoder;
      import io.netty.handler.codec.string.StringEncoder;
      import lombok.extern.slf4j.Slf4j;
      
      /**
       * @author:kyrie
       * @date:2024/3/11 14:04
       * @Description: nettyServer
       **/
      @Slf4j
      public class NettyServer {
      
          /**
           * 接受请求的处理组
           */
          private final NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
      
          /**
           * 实际处理请求的处理组
           */
          private final NioEventLoopGroup workerGroup = new NioEventLoopGroup(2);
      
          /**
           * 初始化netty
           *
           * @param host hostName
           * @param port portName
           */
          public void initNettyServer(String host, int port) {
              // 引导启动
              ServerBootstrap serverBootstrap = new ServerBootstrap();
      
              serverBootstrap
                      // 绑定起来
                      .group(bossGroup, workerGroup)
                      // 设置channel的类型 【Nio】
                      .channel(NioServerSocketChannel.class)
                      // 设置队列大小
                      .option(ChannelOption.SO_BACKLOG, 1024)
                      // 发送缓冲区大小
                      .option(ChannelOption.SO_SNDBUF, 256 * 1024)
                      // 接收缓冲区大小
                      .option(ChannelOption.SO_RCVBUF, 256 * 1024)
                      // 设置TCP长连接 两小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文
                      .childOption(ChannelOption.SO_KEEPALIVE, true)
                      // 自定义handler【就是一个初始化器 每一个channel都会执行这个initChannel()】 这是直接匿名内部类 也可以写个class去extends
                      .childHandler(new ChannelInitializer<SocketChannel>() {
                          @Override
                          protected void initChannel(SocketChannel ch) {
                              ChannelPipeline pipeline = ch.pipeline();
                              // 添加上编解码
                              pipeline.addLast("decoder", new StringDecoder());
                              pipeline.addLast("encoder", new StringEncoder());
      
                              // 添加上自己的处理器
                              pipeline.addLast("nettyServiceHandler", new NettyServiceHandler());
                          }
                      });
      
              // 绑定对应的host和port
              serverBootstrap.bind(host, port);
      
              log.info("netty启动成功");
      
          }
      
          /**
           * 关闭netty服务
           */
          public void closeNettyServer() {
      
              bossGroup.shutdownGracefully();
      
              workerGroup.shutdownGracefully();
      
              log.info("netty关闭成功");
      
          }
      
      }
      
      
    • 自定义handler

      package com.kyrie.netty.server;
      
      import io.netty.channel.Channel;
      import io.netty.channel.ChannelHandlerContext;
      import io.netty.channel.ChannelInboundHandlerAdapter;
      import lombok.extern.slf4j.Slf4j;
      
      /**
       * @author:kyrie
       * @date:2024/3/11 14:56
       * @Description:
       **/
      @Slf4j
      public class NettyServiceHandler extends ChannelInboundHandlerAdapter {
      
          /**
           * 客户端连接会触发此方法
           *
           * @param ctx 上下文
           * @throws Exception 异常
           */
          @Override
          public void channelActive(ChannelHandlerContext ctx) throws Exception {
              // 获取到当前与服务器连接成功的channel
              Channel channel = ctx.channel();
              log.info("{}:客户端连接成功", channel.remoteAddress());
          }
      
          /**
           * 客户端断开连接会触发此方法
           *
           * @param ctx 上下文
           * @throws Exception 异常
           */
          @Override
          public void channelInactive(ChannelHandlerContext ctx) throws Exception {
              // 获取到当前要断开连接的Channel
              Channel channel = ctx.channel();
              log.info("{}:客户端断开连接", channel.remoteAddress());
          }
      
          /**
           * 读取到客户端发送的消息会触发此方法
           *
           * @param ctx 上下文
           * @param msg 消息对象
           * @throws Exception 异常
           */
          @Override
          public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
              Channel channel = ctx.channel();
              log.info("{}:客户端发生的消息:{}", channel.remoteAddress(), msg);
          }
      
          /**
           * 发生异常会执行此方法
           *
           * @param channelHandlerContext 上下文
           * @param throwable             异常
           * @throws Exception 异常
           */
          @Override
          public void exceptionCaught(ChannelHandlerContext channelHandlerContext, Throwable throwable) throws Exception {
              throwable.printStackTrace();
              channelHandlerContext.close();
          }
      }
      
      
  • boot启动

    package com.kyrie;
    
    import com.kyrie.netty.server.NettyServer;
    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
    
    /**
     * @author:kyrie
     * @date:2024/1/26 09:35
     * @Description:
     **/
    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
    public class DemoApp implements CommandLineRunner, DisposableBean {
    
        private NettyServer server;
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApp.class, args);
        }
    
        @Override
        public void run(String... args) {
            server = new NettyServer();
            server.initNettyServer("127.0.0.1", 9877);
        }
    
        @Override
        public void destroy() {
            server.closeNettyServer();
        }
    
    }
    
    
  • 测试

    • 直接用工具发送一个http的请求即可,或者直接写个main()用hutool的方法发一个请求
    • result
      netty初始化成功
      接收到client的消息
  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值