ChannelInitializer: 每个channel都new ChannelHandle

State management

1.业务状态管理-是否登录

ChannelHandler often needs to store some stateful information. The simplest and recommended approach is to use member variables:

 public interface Message {
     // your methods here
 }

 public class DataServerHandler extends SimpleChannelInboundHandler<Message> {

     private boolean loggedIn;

      @Override
     public void channelRead0(ChannelHandlerContext ctx, Message message) {
         Channel ch = e.getChannel();
         if (message instanceof LoginMessage) {
             authenticate((LoginMessage) message);
             loggedIn = true;
         } else (message instanceof GetDataMessage) {
             if (loggedIn) {
                 ch.write(fetchSecret((GetDataMessage) message));
             } else {
                 fail();
             }
         }
     }
     ...
 }

 

Because the handler instance has a state variable which is dedicated to one connection, you have to create a new handler instance for each new channel to avoid a race condition where a unauthenticated client can get the confidential information:

// Create a new handler instance per channel.
 // See ChannelInitializer.initChannel(Channel).
 public class DataServerInitializer extends ChannelInitializer<Channel> {
      @Override
     public void initChannel(Channel channel) {
         channel.pipeline().addLast("handler", new DataServerHandler());
     }
 }

 

2。channel 自身状态管理

public class HeartbeatHandlerInitializer extends ChannelInitializer<Channel> {

    private static final int READ_IDEL_TIME_OUT = 10; // 读超时
    private static final int WRITE_IDEL_TIME_OUT = 10;// 写超时
    private static final int ALL_IDEL_TIME_OUT = 0; // 所有超时

    @Override
    protected void initChannel(Channel ch) throws Exception {
        System.out.println( "channelId"    +   ch.id());
        //一直执行,一直打印
        while (ch.eventLoop().iterator().hasNext()){
            System.out.println(ch.eventLoop().iterator().next().inEventLoop());
        }
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new IdleStateHandler(READ_IDEL_TIME_OUT, WRITE_IDEL_TIME_OUT, ALL_IDEL_TIME_OUT, TimeUnit.SECONDS)); // 1
        pipeline.addLast(new HeartbeatServerHandler());
    }
}

 

posted @ 2017-07-31 17:03  等风来。。  Views(671)  Comments(0Edit  收藏  举报
------------------------------------------------------------------------------------------------------------ --------------- 欢迎联系 x.guan.ling@gmail.com--------------- ------------------------------------------------------------------------------------------------------------