Netty4.0学习笔记系列之四:混合使用coder和handler

Posted 奔跑-起点

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Netty4.0学习笔记系列之四:混合使用coder和handler相关的知识,希望对你有一定的参考价值。

Handler如何使用在前面的例子中已经有了示范,那么同样是扩展自ChannelHandler的Encoder和Decoder,与Handler混合后又是如何使用的?本文将通过一个实际的小例子来展示它们的用法。

该例子模拟一个Server和Client,两者之间通过http协议进行通讯,在Server内部通过一个自定义的StringDecoder把httprequest转换成String。Server端处理完成后,通过StringEncoder把String转换成httpresponse,发送给客户端。具体的处理流程如图所示:

其中红色框中的Decoder、Encoder及request都是Netty框架自带的,灰色框中的三个类是我自己实现的。

Server端的类有:Server StringDecoder BusinessHandler StringEncoder四个类。

1、Server 启动netty服务,并注册handler、coder,注意注册的顺序:

[java]  view plain  copy  
  1. package com.guowl.testmulticoderandhandler;  
  2.   
  3. import io.netty.bootstrap.ServerBootstrap;  
  4. import io.netty.channel.ChannelFuture;  
  5. import io.netty.channel.ChannelInitializer;  
  6. import io.netty.channel.ChannelOption;  
  7. import io.netty.channel.EventLoopGroup;  
  8. import io.netty.channel.nio.NioEventLoopGroup;  
  9. import io.netty.channel.socket.SocketChannel;  
  10. import io.netty.channel.socket.nio.NioserverSocketChannel;  
  11. import io.netty.handler.codec.http.HttpRequestDecoder;  
  12. import io.netty.handler.codec.http.HttpResponseEncoder;  
  13.   
  14. // 测试coder 和 handler 的混合使用  
  15. public class Server   
  16.     public void start(int port) throws Exception   
  17.         EventLoopGroup bossGroup = new NioEventLoopGroup();   
  18.         EventLoopGroup workerGroup = new NioEventLoopGroup();  
  19.         try   
  20.             ServerBootstrap b = new ServerBootstrap();   
  21.             b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)   
  22.                     .childHandler(new ChannelInitializer<SocketChannel>()    
  23.                                 @Override  
  24.                                 public void initChannel(SocketChannel ch) throws Exception   
  25.                                     // 都属于ChannelOutboundHandler,逆序执行  
  26.                                     ch.pipeline().addLast(new HttpResponseEncoder());  
  27.                                     ch.pipeline().addLast(new StringEncoder());  
  28.                                       
  29.                                     // 都属于ChannelIntboundHandler,按照顺序执行  
  30.                                     ch.pipeline().addLast(new HttpRequestDecoder());  
  31.                                     ch.pipeline().addLast(new StringDecoder());  
  32.                                     ch.pipeline().addLast(new BusinessHandler());  
  33.                                   
  34.                             ).option(ChannelOption.SO_BACKLOG, 128)   
  35.                     .childOption(ChannelOption.SO_KEEPALIVE, true);   
  36.   
  37.             ChannelFuture f = b.bind(port).sync();   
  38.   
  39.             f.channel().closeFuture().sync();  
  40.          finally   
  41.             workerGroup.shutdownGracefully();  
  42.             bossGroup.shutdownGracefully();  
  43.           
  44.       
  45.   
  46.     public static void main(String[] args) throws Exception   
  47.         Server server = new Server();  
  48.         server.start(8000);  
  49.       
  50.   
2、StringDecoder 把httpRequest转换成String,其中ByteBufToBytes是一个工具类,负责对ByteBuf中的数据进行读取

[java]  view plain  copy  
  1. package com.guowl.testmulticoderandhandler;  
  2.   
  3. import io.netty.channel.ChannelHandlerContext;  
  4. import io.netty.channel.ChannelInboundHandlerAdapter;  
  5. import io.netty.handler.codec.http.HttpContent;  
  6. import io.netty.handler.codec.http.HttpHeaders;  
  7. import io.netty.handler.codec.http.HttpRequest;  
  8.   
  9. import org.slf4j.Logger;  
  10. import org.slf4j.LoggerFactory;  
  11.   
  12. import com.guowl.utils.ByteBufToBytes;  
  13.   
  14. public class StringDecoder extends ChannelInboundHandlerAdapter   
  15.     private static Logger   logger  = LoggerFactory.getLogger(StringDecoder.class);  
  16.     private ByteBufToBytes  reader;  
  17.   
  18.     @Override  
  19.     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception   
  20.         logger.info("StringDecoder : msg's type is " + msg.getClass());  
  21.         if (msg instanceof HttpRequest)   
  22.             HttpRequest request = (HttpRequest) msg;  
  23.             reader = new ByteBufToBytes((int) HttpHeaders.getContentLength(request));  
  24.           
  25.   
  26.         if (msg instanceof HttpContent)   
  27.             HttpContent content = (HttpContent) msg;  
  28.             reader.reading(content.content());  
  29.   
  30.             if (reader.isEnd())   
  31.                 byte[] clientMsg = reader.readFull();  
  32.                 logger.info("StringDecoder : change httpcontent to string ");  
  33.                 ctx.fireChannelRead(new String(clientMsg));  
  34.               
  35.           
  36.       
  37.   
  38.   
3、BusinessHandler 具体处理业务的类,把客户端的请求打印出来,并向客户端发送信息

[java]  view plain  copy  
  1. package com.guowl.testmulticoderandhandler;  
  2.   
  3. import io.netty.channel.ChannelHandlerContext;  
  4. import io.netty.channel.ChannelInboundHandlerAdapter;  
  5.   
  6. import org.slf4j.Logger;  
  7. Memcached学习笔记之四:Memcached统计命令

    web自动化测试-D3-学习笔记之四(Selenium-ActionChainsApi接口详解)

    Unity Shaders学习笔记——SurfaceShader混合纹理

    [分布式系统学习]阅读笔记 Distributed systems for fun and profit 之四 Replication 拷贝

    iOS与EV3混合机器人编程系列之四iOS_WiFi_EV3_Library 剖析之中的一个:WiFi UDP和TCP

    大数据学习系列之四 ----- Hadoop+Hive环境搭建图文详解(单机)