zoukankan      html  css  js  c++  java
  • Netty 协议设计与解析(redis 、http)

    Netty 协议设计与解析(redis 、http)

    一、redis 协议

    redis 消息协议 有个固定的格式, 在客户端向 redis-server 发送命令时 要遵从该消息协议

    Client端代码如下: 向redis 发送命令 set name zhangsan

    @Slf4j
    public class NClient {
        public static void main(String[] args) {
            send();
            System.out.println("finish");
        }
    
    
        private static void send() {
            NioEventLoopGroup group = new NioEventLoopGroup();
            Bootstrap bootstrap = new Bootstrap();
            try {
                bootstrap.group(group)
                        .channel(NioSocketChannel.class)
                        .handler(new ChannelInitializer<NioSocketChannel>() {
                            @Override
                            protected void initChannel(NioSocketChannel ch) throws Exception {
    
                                ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
                                ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){
                                    @Override
                                    public void channelActive(ChannelHandlerContext ctx) throws Exception {
                                        // 换行符
                                        byte[] line = new byte[]{13,10};
                                        
                            
                                        /**
                                         * 执行redis  set name zhangsan  命令  
                                         *   [set, name, zhangsan]
                                         *   *3       表示有 长度为3 的数组
                                         *   $3       表示元素1 的长度为3
                                         *   set       
                                         *   $4       表示元素2 的长度为4
                                         *   name
                                         *   $8       表示元素3 的长度为8
                                         *   zhangsan
                                         */
                                        ByteBuf buf = ctx.alloc().buffer();
                                        buf.writeBytes("*3".getBytes());
                                        buf.writeBytes(line);
                                        buf.writeBytes("$3".getBytes());
                                        buf.writeBytes(line);
                                        buf.writeBytes("set".getBytes());
                                        buf.writeBytes(line);
                                        buf.writeBytes("$4".getBytes());
                                        buf.writeBytes(line);
                                        buf.writeBytes("name".getBytes());
                                        buf.writeBytes(line);
                                        buf.writeBytes("$8".getBytes());
                                        buf.writeBytes(line);
                                        buf.writeBytes("zhangsan".getBytes());
                                        buf.writeBytes(line);  // 最后还有一个换行
                                        ctx.writeAndFlush(buf);
                                    }
                                  // 接收 redis 响应的消息
                                  @Override
               					  public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                            ByteBuf buf = (ByteBuf) msg;
    						System.out.println(buf.toString(Charset.defaultCharset()));
                                  }
                                });
                            }
                        });
                // 连接 redis-server
                ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 6379).sync();
                channelFuture.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                group.shutdownGracefully();
            }
        }
    }
    

    Client端 发送与响应结果

    12:50:26.335 [nioEventLoopGroup-2-1] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0x9579b508, L:/127.0.0.1:49624 - R:localhost/127.0.0.1:6379] WRITE: 37B
             +-------------------------------------------------+
             |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
    +--------+-------------------------------------------------+----------------+
    |00000000| 2a 33 0d 0a 24 33 0d 0a 73 65 74 0d 0a 24 34 0d |*3..$3..set..$4.|
    |00000010| 0a 6e 61 6d 65 0d 0a 24 38 0d 0a 7a 68 61 6e 67 |.name..$8..zhang|
    |00000020| 73 61 6e 0d 0a                                  |san..           |
    +--------+-------------------------------------------------+----------------+
    12:50:26.335 [nioEventLoopGroup-2-1] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0x9579b508, L:/127.0.0.1:49624 - R:localhost/127.0.0.1:6379] FLUSH
    12:50:26.337 [nioEventLoopGroup-2-1] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0x9579b508, L:/127.0.0.1:49624 - R:localhost/127.0.0.1:6379] READ: 5B
             +-------------------------------------------------+
             |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
    +--------+-------------------------------------------------+----------------+
    |00000000| 2b 4f 4b 0d 0a                                  |+OK..           |
    +--------+-------------------------------------------------+----------------+
    +OK
    
    12:50:26.337 [nioEventLoopGroup-2-1] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0x9579b508, L:/127.0.0.1:49624 - R:localhost/127.0.0.1:6379] READ COMPLETE
    
    

    通过redis-cli 查看 写入结果

    二、http 协议

    http协议的编解码 ,Netty已经帮我们封装好了: HttpServerCodec 类。

    HttpServerCodec 可处理 请求解码 和 响应编码

    1.请求解码

    Server端 加入 HttpServerCodec 编码处理器

    @Slf4j
    public class NServer {
        public static void main(String[] args) {
            NioEventLoopGroup boss = new NioEventLoopGroup(1);
            NioEventLoopGroup worker = new NioEventLoopGroup();
            try {
                ServerBootstrap bootstrap = new ServerBootstrap();
                bootstrap.group(boss,worker)
                        .channel(NioServerSocketChannel.class)
                        .childHandler(new ChannelInitializer<NioSocketChannel>() {
                            @Override
                            protected void initChannel(NioSocketChannel ch) throws Exception {
    
                                // 添加日志处理器
                                ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
    
                                // 添加 Http协议编码器
                                ch.pipeline().addLast(new HttpServerCodec());
    
                                // 添加自定义处理器  打印消息类型
                                ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){
                                    @Override
                                    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                        log.debug("{}",msg.getClass());
                                    }
                                });
                            }
                        });
    
                ChannelFuture channelFuture = bootstrap.bind(8080).sync();
    
                channelFuture.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                boss.shutdownGracefully();
                worker.shutdownGracefully();
            }
        }
    }
    

    浏览器 访问 http://localhost:8080/index.html

    Server端收到以下请求结果:

    22:08:53.194 [nioEventLoopGroup-3-1] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0x9114a1c2, L:/127.0.0.1:8080 - R:/127.0.0.1:64467] READ: 696B
             +-------------------------------------------------+
             |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
    +--------+-------------------------------------------------+----------------+
    |00000000| 47 45 54 20 2f 69 6e 64 65 78 2e 68 74 6d 6c 20 |GET /index.html |
    |00000010| 48 54 54 50 2f 31 2e 31 0d 0a 48 6f 73 74 3a 20 |HTTP/1.1..Host: |
    |00000020| 6c 6f 63 61 6c 68 6f 73 74 3a 38 30 38 30 0d 0a |localhost:8080..|
    |00000030| 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 6b 65 65 70 |Connection: keep|
    |00000040| 2d 61 6c 69 76 65 0d 0a 43 61 63 68 65 2d 43 6f |-alive..Cache-Co|
    |00000050| 6e 74 72 6f 6c 3a 20 6d 61 78 2d 61 67 65 3d 30 |ntrol: max-age=0|
    |00000060| 0d 0a 73 65 63 2d 63 68 2d 75 61 3a 20 22 47 6f |..sec-ch-ua: "Go|
    |00000070| 6f 67 6c 65 20 43 68 72 6f 6d 65 22 3b 76 3d 22 |ogle Chrome";v="|
    |00000080| 39 33 22 2c 20 22 20 4e 6f 74 3b 41 20 42 72 61 |93", " Not;A Bra|
    |00000090| 6e 64 22 3b 76 3d 22 39 39 22 2c 20 22 43 68 72 |nd";v="99", "Chr|
    |000000a0| 6f 6d 69 75 6d 22 3b 76 3d 22 39 33 22 0d 0a 73 |omium";v="93"..s|
    |000000b0| 65 63 2d 63 68 2d 75 61 2d 6d 6f 62 69 6c 65 3a |ec-ch-ua-mobile:|
    |000000c0| 20 3f 30 0d 0a 73 65 63 2d 63 68 2d 75 61 2d 70 | ?0..sec-ch-ua-p|
    |000000d0| 6c 61 74 66 6f 72 6d 3a 20 22 57 69 6e 64 6f 77 |latform: "Window|
    |000000e0| 73 22 0d 0a 55 70 67 72 61 64 65 2d 49 6e 73 65 |s"..Upgrade-Inse|
    |000000f0| 63 75 72 65 2d 52 65 71 75 65 73 74 73 3a 20 31 |cure-Requests: 1|
    |00000100| 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 4d 6f |..User-Agent: Mo|
    |00000110| 7a 69 6c 6c 61 2f 35 2e 30 20 28 57 69 6e 64 6f |zilla/5.0 (Windo|
    |00000120| 77 73 20 4e 54 20 31 30 2e 30 3b 20 57 69 6e 36 |ws NT 10.0; Win6|
    |00000130| 34 3b 20 78 36 34 29 20 41 70 70 6c 65 57 65 62 |4; x64) AppleWeb|
    |00000140| 4b 69 74 2f 35 33 37 2e 33 36 20 28 4b 48 54 4d |Kit/537.36 (KHTM|
    |00000150| 4c 2c 20 6c 69 6b 65 20 47 65 63 6b 6f 29 20 43 |L, like Gecko) C|
    |00000160| 68 72 6f 6d 65 2f 39 33 2e 30 2e 34 35 37 37 2e |hrome/93.0.4577.|
    |00000170| 36 33 20 53 61 66 61 72 69 2f 35 33 37 2e 33 36 |63 Safari/537.36|
    |00000180| 0d 0a 41 63 63 65 70 74 3a 20 74 65 78 74 2f 68 |..Accept: text/h|
    |00000190| 74 6d 6c 2c 61 70 70 6c 69 63 61 74 69 6f 6e 2f |tml,application/|
    |000001a0| 78 68 74 6d 6c 2b 78 6d 6c 2c 61 70 70 6c 69 63 |xhtml+xml,applic|
    |000001b0| 61 74 69 6f 6e 2f 78 6d 6c 3b 71 3d 30 2e 39 2c |ation/xml;q=0.9,|
    |000001c0| 69 6d 61 67 65 2f 61 76 69 66 2c 69 6d 61 67 65 |image/avif,image|
    |000001d0| 2f 77 65 62 70 2c 69 6d 61 67 65 2f 61 70 6e 67 |/webp,image/apng|
    |000001e0| 2c 2a 2f 2a 3b 71 3d 30 2e 38 2c 61 70 70 6c 69 |,*/*;q=0.8,appli|
    |000001f0| 63 61 74 69 6f 6e 2f 73 69 67 6e 65 64 2d 65 78 |cation/signed-ex|
    |00000200| 63 68 61 6e 67 65 3b 76 3d 62 33 3b 71 3d 30 2e |change;v=b3;q=0.|
    |00000210| 39 0d 0a 53 65 63 2d 46 65 74 63 68 2d 53 69 74 |9..Sec-Fetch-Sit|
    |00000220| 65 3a 20 6e 6f 6e 65 0d 0a 53 65 63 2d 46 65 74 |e: none..Sec-Fet|
    |00000230| 63 68 2d 4d 6f 64 65 3a 20 6e 61 76 69 67 61 74 |ch-Mode: navigat|
    |00000240| 65 0d 0a 53 65 63 2d 46 65 74 63 68 2d 55 73 65 |e..Sec-Fetch-Use|
    |00000250| 72 3a 20 3f 31 0d 0a 53 65 63 2d 46 65 74 63 68 |r: ?1..Sec-Fetch|
    |00000260| 2d 44 65 73 74 3a 20 64 6f 63 75 6d 65 6e 74 0d |-Dest: document.|
    |00000270| 0a 41 63 63 65 70 74 2d 45 6e 63 6f 64 69 6e 67 |.Accept-Encoding|
    |00000280| 3a 20 67 7a 69 70 2c 20 64 65 66 6c 61 74 65 2c |: gzip, deflate,|
    |00000290| 20 62 72 0d 0a 41 63 63 65 70 74 2d 4c 61 6e 67 | br..Accept-Lang|
    |000002a0| 75 61 67 65 3a 20 7a 68 2d 43 4e 2c 7a 68 3b 71 |uage: zh-CN,zh;q|
    |000002b0| 3d 30 2e 39 0d 0a 0d 0a                         |=0.9....        |
    +--------+-------------------------------------------------+----------------+
    22:08:53.209 [nioEventLoopGroup-3-1] DEBUG nettydemo.plaster.NServer - class io.netty.handler.codec.http.DefaultHttpRequest
    22:08:53.209 [nioEventLoopGroup-3-1] DEBUG nettydemo.plaster.NServer - class io.netty.handler.codec.http.LastHttpContent$1
    

    由结果 可见 该HTTP 解码器 将请求 解析成了两个类 DefaultHttpRequest(HttpRequest)LastHttpContent(HttpContent)

    如果我们接下来 想针对这两个类做特殊处理可以使用 SimpleChannelInboundHandler<针对类的类名> 处理器

     ServerBootstrap bootstrap = new ServerBootstrap();
                bootstrap.group(boss,worker)
                        .channel(NioServerSocketChannel.class)
                        .childHandler(new ChannelInitializer<NioSocketChannel>() {
                            @Override
                            protected void initChannel(NioSocketChannel ch) throws Exception {
    
                                // 添加日志处理器
                                ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
    
                                // 添加 Http协议编码器
                                ch.pipeline().addLast(new HttpServerCodec());
    
                                // 根据 消息解析后序列化出来的的 类型  来做特殊处理
                                // 这里处理 HttpRequest类
                                ch.pipeline().addLast(new SimpleChannelInboundHandler<HttpRequest>() {
                                    @Override
                                    protected void channelRead0(ChannelHandlerContext ctx, HttpRequest msg) throws Exception {
                                        // 获取请求
                                        log.debug(msg.uri());
                                    }
                                });
                            }
                        });
    

    2.响应编码

    Server端代码

    @Slf4j
    public class NServer {
        public static void main(String[] args) {
            NioEventLoopGroup boss = new NioEventLoopGroup(1);
            NioEventLoopGroup worker = new NioEventLoopGroup();
            try {
                ServerBootstrap bootstrap = new ServerBootstrap();
                bootstrap.group(boss,worker)
                        .channel(NioServerSocketChannel.class)
                        .childHandler(new ChannelInitializer<NioSocketChannel>() {
                            @Override
                            protected void initChannel(NioSocketChannel ch) throws Exception {
    
                                // 添加日志处理器
                                ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
    
                                // 添加 Http协议编码器
                                ch.pipeline().addLast(new HttpServerCodec());
    
                                // 根据 消息解析后序列化出来的的 类型  来做特殊处理
                                ch.pipeline().addLast(new SimpleChannelInboundHandler<HttpRequest>() {
                                    @Override
                                    protected void channelRead0(ChannelHandlerContext ctx, HttpRequest msg) throws Exception {
                                        // 获取请求
                                        log.debug(msg.uri());
    
                                        //返回响应
                                        DefaultFullHttpResponse response =
                                                new DefaultFullHttpResponse(msg.protocolVersion(),HttpResponseStatus.OK);
    
                                        response.content().writeBytes("<h1> Hello,World!<h1>".getBytes());
                                        //返回响应
                                        ctx.writeAndFlush(response);
                                    }
                                });
                            }
                        });
    
                ChannelFuture channelFuture = bootstrap.bind(8080).sync();
    
                channelFuture.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                boss.shutdownGracefully();
                worker.shutdownGracefully();
            }
        }
    }
    

    浏览器 访问 http://localhost:8080/index.html

    Server端日志打印:

    22:22:14.836 [nioEventLoopGroup-3-1] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0x73471bf7, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:59442] READ: 696B
             +-------------------------------------------------+
             |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
    +--------+-------------------------------------------------+----------------+
    |00000000| 47 45 54 20 2f 69 6e 64 65 78 2e 68 74 6d 6c 20 |GET /index.html |
    |00000010| 48 54 54 50 2f 31 2e 31 0d 0a 48 6f 73 74 3a 20 |HTTP/1.1..Host: |
    |00000020| 6c 6f 63 61 6c 68 6f 73 74 3a 38 30 38 30 0d 0a |localhost:8080..|
    |00000030| 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 6b 65 65 70 |Connection: keep|
    |00000040| 2d 61 6c 69 76 65 0d 0a 43 61 63 68 65 2d 43 6f |-alive..Cache-Co|
    |00000050| 6e 74 72 6f 6c 3a 20 6d 61 78 2d 61 67 65 3d 30 |ntrol: max-age=0|
    |00000060| 0d 0a 73 65 63 2d 63 68 2d 75 61 3a 20 22 47 6f |..sec-ch-ua: "Go|
    |00000070| 6f 67 6c 65 20 43 68 72 6f 6d 65 22 3b 76 3d 22 |ogle Chrome";v="|
    |00000080| 39 33 22 2c 20 22 20 4e 6f 74 3b 41 20 42 72 61 |93", " Not;A Bra|
    |00000090| 6e 64 22 3b 76 3d 22 39 39 22 2c 20 22 43 68 72 |nd";v="99", "Chr|
    |000000a0| 6f 6d 69 75 6d 22 3b 76 3d 22 39 33 22 0d 0a 73 |omium";v="93"..s|
    |000000b0| 65 63 2d 63 68 2d 75 61 2d 6d 6f 62 69 6c 65 3a |ec-ch-ua-mobile:|
    |000000c0| 20 3f 30 0d 0a 73 65 63 2d 63 68 2d 75 61 2d 70 | ?0..sec-ch-ua-p|
    |000000d0| 6c 61 74 66 6f 72 6d 3a 20 22 57 69 6e 64 6f 77 |latform: "Window|
    |000000e0| 73 22 0d 0a 55 70 67 72 61 64 65 2d 49 6e 73 65 |s"..Upgrade-Inse|
    |000000f0| 63 75 72 65 2d 52 65 71 75 65 73 74 73 3a 20 31 |cure-Requests: 1|
    |00000100| 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 4d 6f |..User-Agent: Mo|
    |00000110| 7a 69 6c 6c 61 2f 35 2e 30 20 28 57 69 6e 64 6f |zilla/5.0 (Windo|
    |00000120| 77 73 20 4e 54 20 31 30 2e 30 3b 20 57 69 6e 36 |ws NT 10.0; Win6|
    |00000130| 34 3b 20 78 36 34 29 20 41 70 70 6c 65 57 65 62 |4; x64) AppleWeb|
    |00000140| 4b 69 74 2f 35 33 37 2e 33 36 20 28 4b 48 54 4d |Kit/537.36 (KHTM|
    |00000150| 4c 2c 20 6c 69 6b 65 20 47 65 63 6b 6f 29 20 43 |L, like Gecko) C|
    |00000160| 68 72 6f 6d 65 2f 39 33 2e 30 2e 34 35 37 37 2e |hrome/93.0.4577.|
    |00000170| 36 33 20 53 61 66 61 72 69 2f 35 33 37 2e 33 36 |63 Safari/537.36|
    |00000180| 0d 0a 41 63 63 65 70 74 3a 20 74 65 78 74 2f 68 |..Accept: text/h|
    |00000190| 74 6d 6c 2c 61 70 70 6c 69 63 61 74 69 6f 6e 2f |tml,application/|
    |000001a0| 78 68 74 6d 6c 2b 78 6d 6c 2c 61 70 70 6c 69 63 |xhtml+xml,applic|
    |000001b0| 61 74 69 6f 6e 2f 78 6d 6c 3b 71 3d 30 2e 39 2c |ation/xml;q=0.9,|
    |000001c0| 69 6d 61 67 65 2f 61 76 69 66 2c 69 6d 61 67 65 |image/avif,image|
    |000001d0| 2f 77 65 62 70 2c 69 6d 61 67 65 2f 61 70 6e 67 |/webp,image/apng|
    |000001e0| 2c 2a 2f 2a 3b 71 3d 30 2e 38 2c 61 70 70 6c 69 |,*/*;q=0.8,appli|
    |000001f0| 63 61 74 69 6f 6e 2f 73 69 67 6e 65 64 2d 65 78 |cation/signed-ex|
    |00000200| 63 68 61 6e 67 65 3b 76 3d 62 33 3b 71 3d 30 2e |change;v=b3;q=0.|
    |00000210| 39 0d 0a 53 65 63 2d 46 65 74 63 68 2d 53 69 74 |9..Sec-Fetch-Sit|
    |00000220| 65 3a 20 6e 6f 6e 65 0d 0a 53 65 63 2d 46 65 74 |e: none..Sec-Fet|
    |00000230| 63 68 2d 4d 6f 64 65 3a 20 6e 61 76 69 67 61 74 |ch-Mode: navigat|
    |00000240| 65 0d 0a 53 65 63 2d 46 65 74 63 68 2d 55 73 65 |e..Sec-Fetch-Use|
    |00000250| 72 3a 20 3f 31 0d 0a 53 65 63 2d 46 65 74 63 68 |r: ?1..Sec-Fetch|
    |00000260| 2d 44 65 73 74 3a 20 64 6f 63 75 6d 65 6e 74 0d |-Dest: document.|
    |00000270| 0a 41 63 63 65 70 74 2d 45 6e 63 6f 64 69 6e 67 |.Accept-Encoding|
    |00000280| 3a 20 67 7a 69 70 2c 20 64 65 66 6c 61 74 65 2c |: gzip, deflate,|
    |00000290| 20 62 72 0d 0a 41 63 63 65 70 74 2d 4c 61 6e 67 | br..Accept-Lang|
    |000002a0| 75 61 67 65 3a 20 7a 68 2d 43 4e 2c 7a 68 3b 71 |uage: zh-CN,zh;q|
    |000002b0| 3d 30 2e 39 0d 0a 0d 0a                         |=0.9....        |
    +--------+-------------------------------------------------+----------------+
    22:22:14.851 [nioEventLoopGroup-3-1] DEBUG nettydemo.plaster.NServer - /index.html
    22:22:14.855 [nioEventLoopGroup-3-1] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0x73471bf7, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:59442] WRITE: 40B
             +-------------------------------------------------+
             |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
    +--------+-------------------------------------------------+----------------+
    |00000000| 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d |HTTP/1.1 200 OK.|
    |00000010| 0a 0d 0a 3c 68 31 3e 20 48 65 6c 6c 6f 2c 57 6f |...<h1> Hello,Wo|
    |00000020| 72 6c 64 21 3c 68 31 3e                         |rld!<h1>        |
    +--------+-------------------------------------------------+----------------+
    22:22:14.855 [nioEventLoopGroup-3-1] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0x73471bf7, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:59442] FLUSH
    

    浏览器结果:

    由浏览器响应结果 可看见左上角 一直在转圈 , 这是因为我们服务端没有告诉浏览器 返回响应的长度是多少,所以浏览器在一直不停的转圈等待(误以为还有更多的响应会到来)。

    因此 我们要在响应头 中告知浏览器 返回的响应长度是多少。

    修改代码如下:

                                // 根据 消息解析后序列化出来的的 类型  来做特殊处理
                                ch.pipeline().addLast(new SimpleChannelInboundHandler<HttpRequest>() {
                                    @Override
                                    protected void channelRead0(ChannelHandlerContext ctx, HttpRequest msg) throws Exception {
                                        // 获取请求
                                        log.debug(msg.uri());
    
                                        //返回响应
                                        DefaultFullHttpResponse response =
                                                new DefaultFullHttpResponse(msg.protocolVersion(),HttpResponseStatus.OK);
    
                                        // 加上响应长度
                                        byte[] bytes = "<h1> Hello,World!<h1>".getBytes();
                                        response.headers().setInt(CONTENT_LENGTH,bytes.length);
                                        response.content().writeBytes(bytes);
    
                                        //返回响应
                                        ctx.writeAndFlush(response);
                                    }
                                });
    
    万般皆下品,唯有读书高!
  • 相关阅读:
    django regroup的相关知识点
    python学习
    python os的一点心得
    python字符串替换的2种有效方法
    python的缩进格式真的不好吗?
    django的哲学很耐人回味
    python 抓取网页的方法
    分享一点python 编码设置的知识
    python apply的一点知识
    今天休息真舒服
  • 原文地址:https://www.cnblogs.com/s686zhou/p/15260450.html
Copyright © 2011-2022 走看看