netty学习记录

  • NioEventLoopGroup

  1. 线程数量默认为:处理器数量*2
        DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt(
                "io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));
  • ChannelInboundHandlerAdapter

  1.channelRead,msg正确处理

//方式一
public void channelRead(ChannelHandlerContext ctx, Object msg) {
    try {
        // Do something with msg
    } finally {
        ReferenceCountUtil.release(msg);
    }
}
//方式二
public void channelRead(ChannelHandlerContext ctx, Object msg) { 
    // Netty releases it for you when it is written out to the wire
    ctx.write(msg); // (1)
    ctx.flush(); // (2)
}
  •  DefaultChannelGroup

  1. 线程安全的channel集合,对channel提供多种操作
  2. 广播一个消息到多个channels
     ChannelGroup recipients = new DefaultChannelGroup();
     recipients.add(channelA);
     recipients.add(channelB);
     //.. 
     recipients.write(ChannelBuffers.copiedBuffer(
             "Service will shut down for maintenance in 5 minutes.",
             CharsetUtil.UTF_8));
  3. 简单关闭多个channels
     ChannelGroup allChannels = new DefaultChannelGroup();
     public static void main(String[] args) throws Exception {     
         ServerBootstrap b = new ServerBootstrap(..);
         //...
         // Start the server
         b.getPipeline().addLast("handler", new MyHandler());     
         Channel serverChannel = b.bind(..);     
         allChannels.add(serverChannel);
          
         //... Wait until the shutdown signal reception ...
         // Close the serverChannel and then all accepted connections.     
         allChannels.close().awaitUninterruptibly();
         b.releaseExternalResources();
     }
     public class MyHandler extends SimpleChannelUpstreamHandler {     
         @Override
         public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) {
             // Add all open channels to the global group so that they are
             // closed on shutdown.         
             allChannels.add(e.getChannel());
         }
     }

管理channels

    public void channelActive(ChannelHandlerContext ctx) throws Exception {
//        logger.debug("channelActive");
        NettyServer.ALL_CHANNELS.add(ctx.channel());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
//        logger.debug("channelInactive");
        NettyServer.ALL_CHANNELS.remove(ctx.channel());
    }
  • ChannelHandlerContext记录问题

  1. 如果要在内存记下ctx,要注意记录的是哪一个
        protected void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline pipeline = ch.pipeline();
    
            // Add the message codec first,
            pipeline.addLast("decode", new NetDecodeHandler(serverManager.getConfig().baseProtocol));
            pipeline.addLast("encode", new NetEncodeHandler(serverManager.getConfig().baseProtocol));
    
            // and then business logic.
            pipeline.addLast("serverHandler", new NetServerHandler(serverManager));
            
            Glog.debug("NetServerInitializer:pipeline={}", pipeline);
    }

    假如在NetEncodeHandler中记录ctx,调用ctx.writeAndFlush将直接写入到pipeline中的headercontext,不会经过NetEncodeHandler处理。通常应该记录

    NetServerHandler中的ctx,这时候调用ctx.writeAndFlush将会经过
    NetEncodeHandler处理
    public class NetDecodeHandler extends ByteToMessageDecoder {
        private IProtocol baseProtocol;
    
        public NetDecodeHandler(IProtocol baseProtocol) {
            this.baseProtocol = baseProtocol;
        }
        
        @Override
        protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
            if(!in.isReadable() || in.readableBytes() < 4) {
                return;
            }
            while (in.readableBytes() >= 4) {
                in.markReaderIndex();
                int dataLength = in.readInt();
                if (in.readableBytes() < dataLength) {
                    in.resetReaderIndex();
                    return;
                }
                byte[] data = new byte[dataLength];
                in.readBytes(data);
                out.add(baseProtocol.decode(data));
            }
        }
    
    }

     

posted on 2017-05-26 00:24  bestan  阅读(210)  评论(0)    收藏  举报