ChannelHandlerContext

ChannelHandlerContext代表了一个ChannelHandler和ChannelPipeline之间的关系,ChannelHandlerContext创建于ChannelHandler被载入到ChannelPipeline的时候,ChannelHandlerContext主要功能是管理在同一ChannelPipeline中各个ChannelHandler的交互
ChannelHandlerContext,Channel,ChannelPipeline提供的一些方法,下图时三者者之间的关系

ByteToMessageDecoder

一个抽象类需要我们自己重写decode方法

  1. class ByteToIntegerDecoder extends ByteToMessageDecoder{
  2. @Override
  3. protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
  4. while(in.readableBytes() > 4){
  5. out.add(in.readInt());
  6. }
  7. }
  8. }

ctx是decode属于的ChannelHandlerContext,in是用来读取的数据,out是我们转换后的对象列表

channelRead

  1. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  2. if (msg instanceof ByteBuf) {
  3. RecyclableArrayList out = RecyclableArrayList.newInstance();
  4. try {
  5. ByteBuf data = (ByteBuf) msg;
  6. first = cumulation == null;
  7. if (first) {
  8. cumulation = data;
  9. } else {
  10. cumulation = cumulator.cumulate(ctx.alloc(), cumulation, data);
  11. }
  12. callDecode(ctx, cumulation, out);
  13. } catch (DecoderException e) {
  14. throw e;
  15. } catch (Throwable t) {
  16. throw new DecoderException(t);
  17. } finally {
  18. if (cumulation != null && !cumulation.isReadable()) {
  19. cumulation.release();
  20. cumulation = null;
  21. }
  22. int size = out.size();
  23. for (int i = 0; i < size; i ++) {
  24. ctx.fireChannelRead(out.get(i));
  25. }
  26. out.recycle();
  27. }
  28. } else {
  29. ctx.fireChannelRead(msg);
  30. }
  31. }

cumulation是代表累加的byte数据,即上一次decode剩下的byte,cumulator是累加器,默认使用MERGE_CUMULATOR就是使用内存复制来进行累加。累加完之后调用callDecode(ctx, cumulation, out),callDecode中循环调用我们要实现的抽象方法decode(ctx,in,out)来解码,知道不能继续解。在finally中对out列表中的每一个对象调用ctx.fireChannelRead(out.get(i))
触发ChannelPipeline后面的ChannelHandler的channelRead事件