使用Springboot + netty 打造聊天服务(一)

06-01 1311阅读

目录

  • 1、创建Springboot工程
    • 1.1、项目创建
    • 1.2、环境配置
      • 1.2.1、检查settings.xml
      • 1.2.2、检查本地仓库
      • 1.3、项目结构配置
        • 1.3.1、配置JDK
        • 1.4、添加依赖
        • 2、构造NettyWebsocketServer
          • 2.1、创建一个 Netty 服务器配置类
          • 2.2、添加自定义handler
          • 3、使用ApiFox调试
            • 3.1、启动服务
            • 3.2、添加Apifox WebSocket接口
            • 3.3、客户端发送数据
            • 3.4、Debug调试数据
            • 3.5、客户端结果
            • 3.6、改造服务端代码
            • 4、总结

              1、创建Springboot工程

              在Idea里创建Springboot工程,Language选择Java,Type选择Maven,Project SDK 选择Java8。

              使用Springboot + netty 打造聊天服务(一)

              1.1、项目创建

              成功创建项目,Sringboot版本 2.7.6,Java版本8。

              使用Springboot + netty 打造聊天服务(一)

              1.2、环境配置

              检查Maven配置,主要检查settings.xml和本地Maven仓库

              使用Springboot + netty 打造聊天服务(一)

              1.2.1、检查settings.xml

              在settings.xml里配置上阿里云镜像

                
                    
                      alimaven
                      central
                      aliyun maven
                      http://maven.aliyun.com/nexus/content/repositories/central/
                    
                
              

              使用Springboot + netty 打造聊天服务(一)

              1.2.2、检查本地仓库

              Maven版本3.6.3,在Maven文件夹下创建了res文件夹,做为Java工程的Maven本地仓库地址,此文件通常都在500MB以上,随着本地项目数而递增。

              使用Springboot + netty 打造聊天服务(一)

              1.3、项目结构配置

              打开【Project Structure】

              使用Springboot + netty 打造聊天服务(一)

              1.3.1、配置JDK

              修改SDK、Language level等配置。

              使用Springboot + netty 打造聊天服务(一)

              使用Springboot + netty 打造聊天服务(一)

              1.4、添加依赖

              上述操作都是打基础,搭架子和配置环境,下一步我们需要加载netty 的相关依赖包。

              在 pom.xml 文件中添加 Netty 和 Spring Boot 相关的依赖:

                  
                      org.springframework.boot
                      spring-boot-starter
                  
                  
                      io.netty
                      netty-all
                      4.1.68.Final 
                  
              
              

              2、构造NettyWebsocketServer

              2.1、创建一个 Netty 服务器配置类

              import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
              import org.springframework.context.annotation.Configuration;
              import io.netty.channel.socket.nio.NioServerSocketChannel;
              import io.netty.handler.codec.http.HttpObjectAggregator;
              import io.netty.handler.codec.http.HttpServerCodec;
              import io.netty.handler.stream.ChunkedWriteHandler;
              import io.netty.handler.timeout.IdleStateHandler;
              import io.netty.channel.nio.NioEventLoopGroup;
              import io.netty.channel.socket.SocketChannel;
              import io.netty.bootstrap.ServerBootstrap;
              import javax.annotation.PostConstruct;
              import lombok.extern.slf4j.Slf4j;
              import io.netty.channel.*;
              @Slf4j
              @Configuration
              public class NettyWebsocketServer {
                  //bossGroup 连接线程组,主要负责接受客户端连接
                  EventLoopGroup bossGroup = new NioEventLoopGroup(1);
                  private EventLoopGroup workerGroup = new NioEventLoopGroup();
                  private ChannelFuture channelFuture;
                  @PostConstruct
                  public void start() throws InterruptedException {
                      try {
                          ServerBootstrap b = new ServerBootstrap();
                          b.group(bossGroup, workerGroup)
                                  .channel(NioServerSocketChannel.class)
                                  .option(ChannelOption.SO_BACKLOG, 128)
                                  .childOption(ChannelOption.SO_KEEPALIVE, true)
                                  .childHandler(new ChannelInitializer() {
                                      @Override
                                      protected void initChannel(SocketChannel socketChannel) throws Exception {
                                          ChannelPipeline pipeline = socketChannel.pipeline();
                                          // 因为使用 HTTP 协议,所以需要 HTTP编码器,解码器
                                          pipeline.addLast(new HttpServerCodec());
                                          // 以块方式,添加 chunkedWriter 处理器
                                          pipeline.addLast(new ChunkedWriteHandler());
                                          /**
                                           * 1. http数据在传输中是分段的,HttpObjectAggregator 可以把多个段聚合起来
                                           * 2. 这就是为什么当浏览器发送大量数据时,就会发出多次 http请求的原因
                                           */
                                          pipeline.addLast(new HttpObjectAggregator(8192));
                                          // 保存用户ip
                                          // pipeline.addLast(new HttpHeadersHandler());
                                          pipeline.addLast(new WebSocketServerProtocolHandler("/chat"));
                                          pipeline.addLast(new IdleStateHandler(60, 5, 0));
                                          pipeline.addLast(new ChatHandler());  //添加自定义handler
                                      }
                                  });
                          // Bind and start to accept incoming connections.
                          channelFuture = b.bind(9091).sync();
                          if(channelFuture.isSuccess()) {
                              log.info("netty启动成功");
                          }
                          // 对通道关闭进行监听
                          channelFuture.channel().closeFuture().sync();
                      } finally {
                          if (channelFuture != null && channelFuture.isSuccess()) {
                              System.out.println("Netty server started on port 9091");
                          } else {
                              System.err.println("Netty server failed to start");
                          }
                      }
                  }
              }
              

              2.2、添加自定义handler

              创建一个自定义的 ChannelHandler 来处理客户端的请求:

              import io.netty.channel.ChannelHandlerContext;
              import io.netty.channel.ChannelInboundHandlerAdapter;
              public class ChatHandler extends ChannelInboundHandlerAdapter {
                  @Override
                  public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                      // 处理收到的消息
                      System.out.println("Received message: " + msg);
                      ctx.writeAndFlush("Message received: " + msg);
                  }
                  @Override
                  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
                      cause.printStackTrace();
                      ctx.close();
                  }
              }
              

              3、使用ApiFox调试

              3.1、启动服务

              使用Springboot + netty 打造聊天服务(一)

              3.2、添加Apifox WebSocket接口

              使用Springboot + netty 打造聊天服务(一)

              输入ws接口地址,成功连接上netty服务

              使用Springboot + netty 打造聊天服务(一)

              3.3、客户端发送数据

              使用Springboot + netty 打造聊天服务(一)

              3.4、Debug调试数据

              这里可以看到已经接收到数据了。

              我们在Debug数据时,可以看到msg的data类型

              TextWebSocketFrame(data: PooledUnsafeDirectByteBuf(ridx: 0, widx: 61, cap: 61))

              使用Springboot + netty 打造聊天服务(一)

              3.5、客户端结果

              客户端收不到服务端回复的消息。

              使用Springboot + netty 打造聊天服务(一)

              3.6、改造服务端代码

              使用Springboot + netty 打造聊天服务(一)

              查看数据结果

              使用Springboot + netty 打造聊天服务(一)

              4、总结

              在文章里,我们实现了Springboot 集成netty,并使用apiFox客户端发送了消息到netty服务,最终客户端收到服务端的应答。

              下一章节,我们讲解解码器的使用,使得我们的数据可以可视化,以及正常的展示。

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码