千家信息网

Netty中怎么实现前端发送消息,后端接收消息并返回

发表于:2025-01-23 作者:千家信息网编辑
千家信息网最后更新 2025年01月23日,这篇文章主要讲解了"Netty中怎么实现前端发送消息,后端接收消息并返回",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Netty中怎么实现前端发送消息
千家信息网最后更新 2025年01月23日Netty中怎么实现前端发送消息,后端接收消息并返回

这篇文章主要讲解了"Netty中怎么实现前端发送消息,后端接收消息并返回",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Netty中怎么实现前端发送消息,后端接收消息并返回"吧!

1、故事牵引

今天通过一个故事来讲解netty,主要讲client和server端和下面的主要实现类。

客户要去ktv唱歌,进入ktv之前,门口会有招待服务生,然后招待服务生看到客户之后,会安排你们给ktv内部服务生给你们安排房间,然后带你们进入ktv房间唱歌,准备开始唱歌就要打开音乐,选好歌曲,打开灯光等因素,之后这个期间你们可能会让唱歌的服务生来助唱,让会跳舞的服务生给你们跳舞,甚至让服务生带来酒或者吃的,直到你们唱歌结束付完钱离开为止,整个过程就算结束。

专有名词解释:

client端:客户

server端:ktv

mainGroup或者boosGroup:主线程组,相当于ktv门口外的招待服务生

subGroup或者workerGroup:子线程组,相当于ktv内部服务生,负责安排房间的,由招待服务生通知内部服务生安排给他们的

ServerBootstrap :客户进入ktv之前到离开ktv之后的整个流程

HelloServerInitializer:进入ktv房间之后的整个流程

CustomHandler :分别代表唱歌服务生、端茶送水服务生、跳舞服务生各个实现的功能等等

1、NIO图

2、server端
import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.Channel;import io.netty.channel.ChannelFuture;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;/** * @Description: 实现客户端发送一个请求,服务器会返回 hello netty */public class HelloServer {   public static void main(String[] args) throws Exception {      // 定义一对线程组      // 主线程组, 用于接受客户端的连接,但是不做任何处理,跟老板一样,不做事      EventLoopGroup bossGroup = new NioEventLoopGroup();      // 从线程组, 老板线程组会把任务丢给他,让手下线程组去做任务      EventLoopGroup workerGroup = new NioEventLoopGroup();            try {         // netty服务器的创建, ServerBootstrap 是一个启动类         ServerBootstrap serverBootstrap = new ServerBootstrap();         serverBootstrap.group(bossGroup, workerGroup)        // 设置主从线程组                     .channel(NioServerSocketChannel.class) // 设置nio的双向通道                     .childHandler(new HelloServerInitializer()); // 子处理器,用于处理workerGroup                  // 启动server,并且设置8088为启动的端口号,同时启动方式为同步         ChannelFuture channelFuture = serverBootstrap.bind(8088).sync();                  // 监听关闭的channel,设置位同步方式         channelFuture.channel().closeFuture().sync();      } finally {         bossGroup.shutdownGracefully();         workerGroup.shutdownGracefully();      }   }}
3、创建处理器
import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.http.HttpServerCodec;/** * @Description: 初始化器,channel注册后,会执行里面的相应的初始化方法 */public class HelloServerInitializer extends ChannelInitializer {   @Override   protected void initChannel(SocketChannel channel) throws Exception {      // 通过SocketChannel去获得对应的管道      ChannelPipeline pipeline = channel.pipeline();            // 通过管道,添加handler      // HttpServerCodec是由netty自己提供的助手类,可以理解为拦截器      // 当请求到服务端,我们需要做解码,响应到客户端做编码      pipeline.addLast("HttpServerCodec", new HttpServerCodec());            // 添加自定义的助手类,返回 "hello netty~"      pipeline.addLast("customHandler", new CustomHandler());   }}
4、创建助手类
import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.Channel;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.codec.http.DefaultFullHttpResponse;import io.netty.handler.codec.http.FullHttpResponse;import io.netty.handler.codec.http.HttpHeaderNames;import io.netty.handler.codec.http.HttpObject;import io.netty.handler.codec.http.HttpRequest;import io.netty.handler.codec.http.HttpResponseStatus;import io.netty.handler.codec.http.HttpVersion;import io.netty.util.CharsetUtil;/** * @Description: 创建自定义助手类 */// SimpleChannelInboundHandler: 对于请求来讲,其实相当于[入站,入境]public class CustomHandler extends SimpleChannelInboundHandler {   @Override   protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg)          throws Exception {      // 获取channel      Channel channel = ctx.channel();            if (msg instanceof HttpRequest) {         // 显示客户端的远程地址         System.out.println(channel.remoteAddress());                  // 定义发送的数据消息         ByteBuf content = Unpooled.copiedBuffer("Hello netty~", CharsetUtil.UTF_8);                  // 构建一个http response         FullHttpResponse response =                new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,                      HttpResponseStatus.OK,                      content);         // 为响应增加数据类型和长度         response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");         response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());                  // 把响应刷到客户端         ctx.writeAndFlush(response);      }         }   @Override   public void channelRegistered(ChannelHandlerContext ctx) throws Exception {      System.out.println("channel。。。注册");      super.channelRegistered(ctx);   }   @Override   public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {      System.out.println("channel。。。移除");      super.channelUnregistered(ctx);   }   @Override   public void channelActive(ChannelHandlerContext ctx) throws Exception {      System.out.println("channel。。。活跃");      super.channelActive(ctx);   }   @Override   public void channelInactive(ChannelHandlerContext ctx) throws Exception {      System.out.println("channel。。。不活跃");      super.channelInactive(ctx);   }   @Override   public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {      System.out.println("channeld读取完毕。。。");      super.channelReadComplete(ctx);   }   @Override   public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {      System.out.println("用户事件触发。。。");      super.userEventTriggered(ctx, evt);   }   @Override   public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {      System.out.println("channel可写更改");      super.channelWritabilityChanged(ctx);   }   @Override   public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {      System.out.println("补货到异常");      super.exceptionCaught(ctx, cause);   }   @Override   public void handlerAdded(ChannelHandlerContext ctx) throws Exception {      System.out.println("助手类添加");      super.handlerAdded(ctx);   }   @Override   public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {      System.out.println("助手类移除");      super.handlerRemoved(ctx);   }}
5、pom文件
    io.netty    netty-all    4.1.25.Final
6、启动main函数

打开浏览器:localhost:8088,出现下面错误情况,如果用postman工具的话,就会发现不报错,因为浏览器会自动关闭。

解决方案:将super.exceptionCauht(ctx,case);注释掉就好了

@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {    //super.exceptionCaught(ctx, cause);}

感谢各位的阅读,以上就是"Netty中怎么实现前端发送消息,后端接收消息并返回"的内容了,经过本文的学习后,相信大家对Netty中怎么实现前端发送消息,后端接收消息并返回这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0