zoukankan      html  css  js  c++  java
  • netty ByteToMessageDecoder 分析

        ByteToMessageDecoder
            1.socket 移除时触发,最后次读数据处理
            
                @Override
            public final void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
                ByteBuf buf = internalBuffer();
                 if (buf.isReadable()) {
                    ByteBuf bytes = buf.readBytes(buf.readableBytes());
                    buf.release();
                    ctx.fireChannelRead(bytes);
                }
                cumulation = null;
                ctx.fireChannelReadComplete();
                handlerRemoved0(ctx);
            }
            
            2.读取数据 ByteBuf release,discardSomeReadBytes 方法后面研究
            
             public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                RecyclableArrayList out = RecyclableArrayList.newInstance();//创建包装过的数组
                try {
                    if (msg instanceof ByteBuf) {
                        ByteBuf data = (ByteBuf) msg;
                        if (cumulation == null) { //是否继续读取数据
                            cumulation = data;
                            try {
                                callDecode(ctx, cumulation, out);
                            } finally {
                                if (cumulation != null && !cumulation.isReadable()) {
                                    cumulation.release();
                                    cumulation = null;
                                }
                            }
                        } else {//继续读取处理
                            try {
                                //如果剩余空间不够开创建新空间
                                if (cumulation.writerIndex() > cumulation.maxCapacity() - data.readableBytes()) {
                                    ByteBuf oldCumulation = cumulation;
                                    cumulation = ctx.alloc().buffer(oldCumulation.readableBytes() + data.readableBytes());
                                    cumulation.writeBytes(oldCumulation);
                                    oldCumulation.release();
                                }
                                cumulation.writeBytes(data);
                                callDecode(ctx, cumulation, out);
                            } finally {
                                if (cumulation != null) {
                                    if (!cumulation.isReadable()) {
                                        cumulation.release();
                                        cumulation = null;
                                    } else {
                                        cumulation.discardSomeReadBytes();
                                    }
                                }
                                data.release();
                            }
                        }
                    } else {
                        out.add(msg);
                    }
                } catch (DecoderException e) {
                    throw e;
                } catch (Throwable t) {
                    throw new DecoderException(t);
                } finally {
                    int size = out.size();
                    if (size == 0) {
                        decodeWasNull = true;
                    } else {
                        for (int i = 0; i < size; i ++) {
                            ctx.fireChannelRead(out.get(i));
                        }
                    }
                    out.recycle();
                }
            }
            
            //其实只要管核心代码 decode 调用业务处理
             protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
                try {
                    //循环读取数据
                    while (in.isReadable()) {
                        int outSize = out.size();
                        int oldInputLength = in.readableBytes();
                        decode(ctx, in, out);//业务扩展处理
    
                        // Check if this handler was removed before continuing the loop.
                        // If it was removed, it is not safe to continue to operate on the buffer.
                        //
                        // See https://github.com/netty/netty/issues/1664
                        //如果 handler 删除之前,那么不读取数据了
                        if (ctx.isRemoved()) {
                            break;
                        }
                        //下面写得很不清晰。。。。。
                        
                        if (outSize == out.size()) {
                            if (oldInputLength == in.readableBytes()) {
                                break;
                            } else {
                                continue;
                            }
                        }
    
                        if (oldInputLength == in.readableBytes()) {
                            throw new DecoderException(
                                    StringUtil.simpleClassName(getClass()) +
                                    ".decode() did not read anything but decoded a message.");
                        }
    
                        if (isSingleDecode()) {
                            break;
                        }
                    }
                } catch (DecoderException e) {
                    throw e;
                } catch (Throwable cause) {
                    throw new DecoderException(cause);
                }
            }
  • 相关阅读:
    Android getMeasuredHeight()与getHeight()的区别
    Android控件属性android:visibility的"invisible"与"gone"的区别
    浅谈Android onClick与onLongClick事件触发的问题
    Android ListView中FooterView布局问题
    Android GridView 问题
    Android HTTP POST上传
    监听EditText实时输入
    C++03下的delegate实现-
    delegate委托的C++实现--C++11/14(原创)
    Unity3D 移动平台实现一种大规模(其实跟PC比还是算小规模)动画角色渲染的方案---绝对原创方案。。。
  • 原文地址:https://www.cnblogs.com/solq/p/4308409.html
Copyright © 2011-2022 走看看